您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)如何使用asp.net mvc,boostrap及knockout.js開(kāi)發(fā)微信自定義菜單編輯工具的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
正文
先用bootstrap排個(gè)頁(yè)面框架出來(lái),調(diào)用自定義菜單接口需要用到AccessToken,放個(gè)輸入框輸入AccessToken。也不排除想直接輸入AppId和AppSecret來(lái)獲取AccessToken的用戶,所以還需要下拉菜單來(lái)選擇是輸入AccessToken還是直接獲取AccessToken。為了兼顧微信企業(yè)號(hào)應(yīng)用創(chuàng)建菜單還需要AgentId,CorpId,套件永久授權(quán)碼,SuiteId,SuiteSecret,SuiteTicket,參數(shù)的輸入框大致就是這些。
使用knockout定義好observables監(jiān)控屬性。并綁定到輸入框上。
定義菜單展示及菜單編輯模塊,排版為微信公眾號(hào)菜單三個(gè)大菜單,每個(gè)大菜單下面可以配五個(gè)子菜單。大致思路如下,頁(yè)面排版為六行三列,三個(gè)大菜單未配置滿時(shí)在右側(cè)顯示增加菜單按鈕,
每個(gè)父級(jí)菜單的子菜單未配置滿時(shí)在上方顯示增加菜單按鈕。未配置滿時(shí)以空白div占位。
定義個(gè)函數(shù)生成自定義長(zhǎng)度數(shù)組
使用knockout定義好菜單監(jiān)控屬性,格式為
{ "button": [ { "name": "父級(jí)菜單1", "sub_button": [ { "type": "view", "name": "子菜單1", "url": "" } ] }, { "name": "父級(jí)菜單1", "sub_button": [ { "type": "view", "name": "子菜單2", "url": "" }, { "type": "view", "name": "子菜單1", "url": "" } ] } ] }
定義添加,編輯,刪除菜單函數(shù),定義添加編輯菜單時(shí)臨時(shí)監(jiān)控屬性,定義當(dāng)前編輯菜單索引的監(jiān)控屬性。
一個(gè)一個(gè)編輯菜單還不是很方便,所以還要定義菜單的 上 下 左 右 的移動(dòng),及復(fù)制粘貼功能。
function MenuFormValidate() { $("#MenuForm").validate({ rules: { name: { required: true }, value: { required: false } }, messages: { name: { required: "請(qǐng)輸入名稱" }, value: { required: $("#txtMenuButtonValue").attr("placeholder") } } }); } MenusReset:function () { var menus = JSON.stringify(model.Menus()); model.Menus(undefined); model.Menus(JSON.parse(menus));//刷新菜單對(duì)象 MenuFormValidate();//重新綁定驗(yàn)證方法 }, MenuIndex: ko.observable(), //父級(jí)菜單索引 isEditMenu: ko.observable(false), //是否是編輯菜單 BottonIndex: ko.observable(-1), //編輯菜單的父級(jí)菜單索引 SubBottonIndex: ko.observable(-1), //編輯菜單的子菜單索引 Menu: ko.observable(),//編輯菜單時(shí)臨時(shí)監(jiān)控屬性 CopyMenu: ko.observable(),//復(fù)制的菜單對(duì)象 Copy: function () { //復(fù)制 if (model.Menu() != undefined) { var menu = JSON.stringify(model.Menu()); model.CopyMenu(JSON.parse(menu)); model.Menu(undefined); } }, Paste: function () {//粘貼 if (model.CopyMenu() != undefined) { var menu = JSON.parse(JSON.stringify(model.CopyMenu())); if (model.SubBottonIndex() !== -1 && menu.sub_button != undefined || (!model.isEditMenu() && model.MenuIndex() != undefined)) { delete menu.sub_button; } model.Menu(menu); MenuFormValidate(); } }, Up: function () {//向上移動(dòng) var bottonIndex = model.BottonIndex(); var subBottonIndex = model.SubBottonIndex(); var newSubBottonIndex = subBottonIndex - 1; model.Menus().button[bottonIndex].sub_button[subBottonIndex] = model.Menus().button[bottonIndex].sub_button[newSubBottonIndex]; model.Menus().button[bottonIndex].sub_button[newSubBottonIndex] = model.Menu(); model.MenusReset(); model.SubBottonIndex(newSubBottonIndex); }, Down: function () {//向下移動(dòng) var bottonIndex = model.BottonIndex(); var subBottonIndex = model.SubBottonIndex(); var newSubBottonIndex = subBottonIndex + 1; model.Menus().button[bottonIndex].sub_button[subBottonIndex] = model.Menus().button[bottonIndex].sub_button[newSubBottonIndex]; model.Menus().button[bottonIndex].sub_button[newSubBottonIndex] = model.Menu(); model.MenusReset(); model.SubBottonIndex(newSubBottonIndex); }, Left: function () {//向左移動(dòng) var bottonIndex = model.BottonIndex(); var subBottonIndex = model.SubBottonIndex(); if (subBottonIndex === -1) { var newBottonIndex = bottonIndex - 1; model.Menus().button[bottonIndex] = model.Menus().button[newBottonIndex]; model.Menus().button[newBottonIndex] = model.Menu(); model.MenusReset(); model.BottonIndex(newBottonIndex); } }, Right: function () {//向右移動(dòng) var bottonIndex = model.BottonIndex(); var subBottonIndex = model.SubBottonIndex(); if (subBottonIndex === -1) { var newBottonIndex = bottonIndex + 1; model.Menus().button[bottonIndex] = model.Menus().button[newBottonIndex]; model.Menus().button[newBottonIndex] = model.Menu(); model.MenusReset(); model.BottonIndex(newBottonIndex); } }, EditMenu: function (obj, bottonindex, subbottonindex) {//編輯菜單 model.BottonIndex(bottonindex); model.SubBottonIndex(subbottonindex); model.isEditMenu(true); var data = JSON.stringify(obj); model.Menu(JSON.parse(data)); MenuFormValidate(); }, AddMenu: function (index) {//添加菜單 model.BottonIndex(-1); model.SubBottonIndex(-1); model.isEditMenu(false); model.MenuIndex(index); var menu = { type: "view", name: "", value: "" }; model.Menu(menu); MenuFormValidate(); }, DeleteMenu: function () {//刪除菜單 $(model.Menus().button).each(function (index, item) { if (index === model.BottonIndex() && model.SubBottonIndex() === -1) { model.Menus().button.splice(index, 1); } if (item.sub_button instanceof Array) { $(item.sub_button).each(function (index1) { if (index === model.BottonIndex() && index1 === model.SubBottonIndex()) { item.sub_button.splice(index1, 1); } }); } }); model.Menu(undefined); model.MenuIndex(undefined); model.BottonIndex(-1); model.SubBottonIndex(-1); model.MenusReset(); }, CancelMenuSave: function () {//取消編輯,重置參數(shù) model.Menu(undefined); model.MenuIndex(undefined); model.BottonIndex(-1); model.SubBottonIndex(-1); }, MenuSave: function () {//保存編輯的菜單 if (!$("#MenuForm").data("validator").form()) { return; } if (model.isEditMenu()) { var menuIndex = model.BottonIndex(); var subMenuIndex = model.SubBottonIndex(); if (subMenuIndex === -1) { model.Menus().button[menuIndex] = model.Menu(); } else { model.Menus().button[menuIndex].sub_button[subMenuIndex] = model.Menu(); } } else { if (model.MenuIndex() != undefined) { if (model.Menus().button[model.MenuIndex()].sub_button == undefined) { model.Menus().button[model.MenuIndex()].sub_button = new Array(); } model.Menus().button[model.MenuIndex()].sub_button.unshift(model.Menu()); } else { model.Menus().button.push(model.Menu()); } } model.Menu(undefined); model.MenuIndex(undefined); model.BottonIndex(-1); model.SubBottonIndex(-1); model.MenusReset(); },
綁定好監(jiān)控屬性,生成菜單排版
<div class="panel-body" data-bind="with:Menus" id="divMenu" > <div data-bind="foreach:newArray(3)"> <div class="list-group col-xs-4 clearFill bn"> <!--ko if:($parent.button.length>0 && $parent.button[$index()]!=undefined && $parent.button[$index()].sub_button!=undefined ) --> <!--ko foreach:newArray((4-$parent.button[$index()].sub_button.length)) --> <div class="list-group-item bn"></div> <!--/ko--> <!--ko if:$parent.button[$index()].sub_button.length<5 --> <div class="list-group-item" data-bind="click:function (){$root.AddMenu($index())}"><i class="fa fa-plus"></i> </div> <!--/ko--> <!--ko foreach:($parent.button[$index()].sub_button) --> <div class="list-group-item" data-bind="text:name,attr:{'bottonIndex':$parent.value,'subbottonIndex':$index()},click:function (){$root.EditMenu($data,$parent.value,$index())}"></div> <!--/ko--> <!--/ko --> <!--ko if: $parent.button[$index()]!=undefined && $parent.button[$index()].sub_button==undefined --> <div class="list-group-item bn"></div> <div class="list-group-item bn"></div> <div class="list-group-item bn"></div> <div class="list-group-item bn"></div> <div class="list-group-item" data-bind="click:function (){$root.AddMenu($index())}"><i class="fa fa-plus"></i> </div> <!--/ko--> <!--ko if: $parent.button[$index()]==undefined --> <div class="list-group-item bn"></div> <div class="list-group-item bn"></div> <div class="list-group-item bn"></div> <div class="list-group-item bn"></div> <div class="list-group-item bn"></div> <!--/ko--> </div> </div> <!--ko foreach:button --> <div class="col-xs-4 list-group-item list-group-item-danger" data-bind="text:name,attr:{'bottonindex':$index()},click:function (){$root.EditMenu($data,$index(),-1)}"></div> <!--/ko--> <!--ko if:button.length < 3 --> <div class="col-xs-4 list-group-item" data-bind="click:function (){$root.AddMenu();}"><i class="fa fa-plus"></i> </div> <!--/ko--> <div class="clearfix"></div> <div class="col-xs-12" data-bind="with:$root.Menu,visible:($root.Menu()!=undefined)"> <form id="MenuForm" onsubmit="return false;"> <div class="form-group col-xs-4"> <input type="text" class="form-control" name="name" placeholder="請(qǐng)輸入名稱" data-bind="value:name"> </div> <div class="form-group col-xs-4"> <select class="form-control" onchange="$('#txtMenuButtonValue') .attr('placeholder', $(this).find('option:selected').attr('pl'))" data-bind="value:type"> <option value="view" pl="請(qǐng)輸入U(xiǎn)rl">跳轉(zhuǎn)URL</option> <option value="click" pl="請(qǐng)輸入Key">點(diǎn)擊推事件</option> <option value="scancode_push" pl="請(qǐng)輸入Key">掃碼推事件</option> <option value="scancode_waitmsg" pl="請(qǐng)輸入Key">掃碼推事件且彈出“消息接收中”提示框</option> <option value="pic_sysphoto" pl="請(qǐng)輸入Key">彈出系統(tǒng)拍照發(fā)圖</option> <option value="pic_photo_or_album" pl="請(qǐng)輸入Key">彈出拍照或者相冊(cè)發(fā)圖</option> <option value="pic_weixin" pl="請(qǐng)輸入Key"> 彈出微信相冊(cè)發(fā)圖器</option> <option value="location_select" pl="請(qǐng)輸入Key">彈出地理位置選擇器</option> </select> </div> <div class="form-group col-xs-8"> <input type="text" id="txtMenuButtonValue" name="value" class="form-control" placeholder="請(qǐng)輸入U(xiǎn)rl" data-bind="value:value"> </div> <div class="form-group col-xs-12"> <button type="submit" class="btn btn-primary" data-bind="click:$root.MenuSave">確定</button> <button type="submit" class="btn btn-danger" data-bind="visible:$root.isEditMenu,click:$root.DeleteMenu">刪除</button> <button type="button" class="btn btn-default" title="上移" data-bind="visible:$root.isEditMenu(),disable:!$root.IsUp(),click:$root.Up"><i class="fa fa-chevron-circle-up" aria-hidden="true"></i></button> <button type="button" class="btn btn-default" title="下移" data-bind="visible:$root.isEditMenu(),disable:!$root.IsDown(),click:$root.Down"><i class="fa fa-chevron-circle-down" aria-hidden="true"></i></button> <button type="button" class="btn btn-default" title="左移" data-bind="visible:$root.isEditMenu(),disable:!$root.IsLeft(),click:$root.Left"><i class="fa fa-chevron-circle-left" aria-hidden="true"></i></button> <button type="button" class="btn btn-default" title="右移" data-bind="visible:$root.isEditMenu(),disable:!$root.IsRight(),click:$root.Right"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i></button> <button type="button" class="btn btn-default" title="復(fù)制菜單" data-bind="visible:$root.isEditMenu(),click:$root.Copy">復(fù)制</button> <button type="button" class="btn btn-default" title="粘貼菜單" data-bind="click:$root.Paste">粘貼</button> <button type="submit" class="btn btn-default" data-bind="click:$root.CancelMenuSave">關(guān)閉</button> </div> </form> </div> <div class="clearfix"></div> </div>
最后增加菜單的查詢函數(shù)及發(fā)布函數(shù)。因?yàn)榫庉嫴藛畏奖?,菜單?duì)象和微信自定義菜單接口所需要的json格式不對(duì)應(yīng),所以在查詢現(xiàn)有菜單和發(fā)布菜單時(shí),需要對(duì)json數(shù)據(jù)進(jìn)行一下格式變化。,
EditMenus: function (isQuery) { if (isQuery == undefined) { var menu = {}; menu.button = new Array(); model.Menus(menu); } else { var appId = model.AppId(); var appSecret = model.AppSecret(); var accessToken = model.AccessToken(); var type = model.Type(); var tokenType = model.TokenType(); var corpId = model.CorpId(); var permanentCode = model.PermanentCode(); var agentId = model.AgentId(); var suiteId = model.SuiteId(); var suiteSecret = model.SuiteSecret(); var suiteTicket = model.SuiteTicket(); if (type === "1" && tokenType === "2") { if (appId == undefined || $.trim(appId).length === 0) { alert("請(qǐng)輸入AppId"); return; } if (appSecret == undefined || $.trim(appSecret).length === 0) { alert("請(qǐng)輸入AppSecret"); return; } } else if (type === "2" && tokenType === "2") { if (corpId == undefined || $.trim(corpId).length === 0) { alert("請(qǐng)輸入CorpId"); return; } if (permanentCode == undefined || $.trim(permanentCode).length === 0) { alert("請(qǐng)輸入永久授權(quán)碼"); return; } if (agentId == undefined || $.trim(agentId).length === 0) { alert("請(qǐng)輸入AgentId"); return; } if (suiteId == undefined || $.trim(suiteId).length === 0) { alert("請(qǐng)輸入SuiteId"); return; } if (suiteSecret == undefined || $.trim(suiteSecret).length === 0) { alert("請(qǐng)輸入SuiteSecret"); return; } if (suiteTicket == undefined || $.trim(suiteTicket).length === 0) { alert("請(qǐng)輸入SuiteTicket"); return; } } else if (tokenType === "1") { if (accessToken == undefined || $.trim(accessToken).length === 0) { alert("請(qǐng)輸入AccessToken"); return; } } $("#btnQueryMenu").button("查詢中..."); $.ajax({ url: "", datatype: "JSON", type: "POST", async: true, data: JSON.stringify({ appId: appId, appSecret: appSecret, accessToken: accessToken, type: type, tokenType: tokenType, corpId: corpId, permanentCode: permanentCode, agentId: agentId, suiteId: suiteId, suiteSecret: suiteSecret, suiteTicket: suiteTicket }), contentType: "application/json; charset=UTF-8", success: function (obj) { $("#btnQueryMenu").button("reset"); if (obj.Success) { var data = obj.Data; var menus = JSON.parse(data).menu; $(menus.button).each(function (index, item) { if (item.type === "view") { item.value = item.url; delete item.url; } else { item.value = item.key; delete item.key; } if (item.type == undefined) { item.type = "view"; item.value = ""; } if (item.sub_button instanceof Array) { $(item.sub_button).each(function (index1, item2) { if (item2.type === "view") { item2.value = item2.url; delete item2.url; } else { item2.value = item2.key; delete item2.key; } }); } }); model.Menu(undefined); model.MenuIndex(undefined); model.BottonIndex(-1); model.SubBottonIndex(-1); model.Menus(undefined); model.Menus(menus); } else { alert(obj.Messages); } }, error: function (xmlHttpRequest, textStatus, errorThrown) { $("#btnQueryMenu").button("reset"); console.error(errorThrown); } }); } }, SaveMenus: function () { var menus = JSON.parse(JSON.stringify(model.Menus())); $(menus.button).each(function (index, item) { if (item.type === "view") { item.url = item.value; delete item.value; } else { item.key = item.value; delete item.value; } if (item.sub_button instanceof Array) { $(item.sub_button).each(function (index1, item2) { if (item2.type === "view") { item2.url = item2.value; delete item2.value; } else { item2.key = item2.value; delete item2.value; } }); if (item.sub_button.length > 0) { delete item.key; delete item.url; delete item.type; } else { delete item.sub_button; } } }); console.log(JSON.stringify(menus)); var appId = model.AppId(); var appSecret = model.AppSecret(); var accessToken = model.AccessToken(); var type = model.Type(); var tokenType = model.TokenType(); var agentId = model.AgentId(); var suiteId = model.SuiteId(); var suiteSecret = model.SuiteSecret(); var suiteTicket = model.SuiteTicket(); if (type === "1" && tokenType === "2") { if (appId == undefined || $.trim(appId).length === 0) { alert("請(qǐng)輸入AppId"); return; } if (appSecret == undefined || $.trim(appSecret).length === 0) { alert("請(qǐng)輸入AppSecret"); return; } } else if (type === "2" && tokenType === "2") { if (agentId == undefined || $.trim(agentId).length === 0) { alert("請(qǐng)輸入AgentId"); return; } if (suiteId == undefined || $.trim(suiteId).length === 0) { alert("請(qǐng)輸入SuiteId"); return; } if (suiteSecret == undefined || $.trim(suiteSecret).length === 0) { alert("請(qǐng)輸入SuiteSecret"); return; } if (suiteTicket == undefined || $.trim(suiteTicket).length === 0) { alert("請(qǐng)輸入SuiteTicket"); return; } } else if (tokenType === "1") { if (accessToken == undefined || $.trim(accessToken).length === 0) { alert("請(qǐng)輸入AccessToken"); return; } } $("#btnSubmitMenu").button("發(fā)布中..."); $.ajax({ url: "", datatype: "JSON", type: "POST", async: true, data: JSON.stringify({ appId: appId, appSecret: appSecret, accessToken: accessToken, type: type, tokenType: tokenType, agentId: agentId, suiteId: suiteId, suiteSecret: suiteSecret, suiteTicket: suiteTicket, menu: JSON.stringify(menus) }), contentType: "application/json; charset=UTF-8", success: function (obj) { $("#btnSubmitMenu").button("reset"); if (obj.Success) { alert("發(fā)布成功"); } else { alert(obj.Messages); } }, error: function (xmlHttpRequest, textStatus, errorThrown) { $("#btnSubmitMenu").button("reset"); console.error(errorThrown); } }); }
最終效果如下
感謝各位的閱讀!關(guān)于“如何使用asp.net mvc,boostrap及knockout.js開(kāi)發(fā)微信自定義菜單編輯工具”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。