我正在从两个其他api创建动态菜单。菜单将通过父/子关系创建。这意味着父ajax响应的id将传递给子ajax以获取子记录。
问题是,当我对我的孩子ajax调用使用async false
时,我的网站变慢,并且删除它时,菜单无法呈现。对此有所帮助。
我的代码家长致电
var url;
url = "/_api/lists/getbytitle('GlobalTopNavMenu')/items?$select=Id,Title,Image,hasSubMenu,Link&$filter=Location eq 'GlobalNavigation'";
html = "<ul class='nav navbar-nav nav-topmrgn'>";
$.ajax({
url: url,
method: "GET",
headers: {
"Accept": "application/json; odata=verbose"
},
success: function(data) {
$.each(data.d.results, function(i, item) {
if (item.hasSubMenu == "Yes") {
html += "<li class='dropdown yamm-fw borderLeftY'><a href='#' title='' class='dropdown-toggle' data-toggle='dropdown' role='button' aria-haspopup='true' aria-expanded='false'>" + Res[item.Title] + "<b class='caret'></b></a>";
html += getSubMenu(item.Id) + "</dl>";
html += "<dl class=''><dd class='picHolder'><img alt='' src='/PublishingImages/" + item.Image + "'/></dd></dl></div></div></li></ul></li>";
} else
html += "<li class='yamm-fw borderLeftY'><a href='" + item.Link + "' title='' class='dropdown-toggle' role='link' aria-haspopup='true' aria-expanded='false'>" + Res[item.Title] + "</a></li>";
})
html += "</ul>";
$("#navbar").empty();
$("#navbar").append(html);
}
});
儿童电话
function getSubMenu(id) {
var url = "/_api/lists/getbytitle('GlobalSubNavMenu')/items?$select=Id,Title,Link,ParentMenu/Id,root&$filter=ParentMenu/Id eq " + id + "&$expand=ParentMenu/Id";
var html = "";
$.ajax({
url: url,
method: "GET",
async: false,
headers: {
"Accept": "application/json; odata=verbose"
},
success: function(data) {
if (data.d.results.length < 6)
html += "<ul class='dropdown-menu width500 spaceLeft'>"; //
else
html += "<ul class='dropdown-menu width800 spaceLeft'>";
html += "<li><div class='yamm-content'><div class='row'><dl class='col-sm-3 mega-menu colborderRight'>";
$.each(data.d.results, function(i, item) {
if (i !== 0 && i % 6 == 0)
html += "</dl><dl class='col-sm-3 mega-menu colborderRight'><dd class=''><a href=/" + (item.root ? "" : lang) + item.Link + ">" + Res[item.Title] + "</a></dd>";
else
html += "<dd class=''><a href=/" + (item.root ? "" : lang) + item.Link + ">" + Res[item.Title] + "</a></dd>";
});
}
});
return html;
}
如果我从子函数中删除async false,则菜单将不会呈现。那我该怎么做。
最佳答案
对于async: false
,getSubMenu()
是异步的,因此,getSubMenu()
必须返回promise(良好做法)或接受回调(不良做法),
依赖于从getSubMenu()
获得的数据的代码必须进行相应的分解。
这不是处理异步派生数据的最简单介绍,尤其是因为getSubMenu()
是在循环内调用的。
您需要了解以下内容:jQuery.ajax()
返回一个承诺,使您可以链接.then()
。解决此问题时,您将受益于.then()
的“成功:”回调的巨大力量。Array#map()
将数组映射到您喜欢的新数组。在这里Array#map()
在创建由getSubMenu()
返回的promise数组时特别有用。jQuery.when()
聚合多个promise,并返回一个promise。
这是一个框架化的模式,可以解决您的问题:
$.ajax({...})
.then(function(data) { // then() not success: ...
var promises = data.d.results.map(function(item) {
if (item.hasSubMenu == 'Yes') {
return getSubMenu(item.Id).then(function(subMenu) {
return '...'; // build and return an HTML string here, including the `subMenu` created by `getSubMenu()`.
});
} else {
return '...'; // return hard-coded HTML.
}
});
// At this point, promises is an array comprising some unknown mix of jQuery promises and HTML strings.
return jQuery.when.apply(null, promises).then(function(/* each argument is an HTML fragment, as generated above */) {
var html = Array.prototype.join.call(arguments, ''); // slightly awkward syntax for joining `arguments` into a single string.
$("#navbar").html('...' + html + '...');
});
});
function getSubMenu(id) {
var url = "...";
return $.ajax({...}}) // getSubMenu() must return a promise.
.then(function(data) { // then() not success: ...
var html = "..."; // initial HTML fragment
var arr = data.d.results.map(function(item) {
return '...'; // build and return HTML based on item.
});
// At this point, `arr` is an array of HTML fragments, that can be concatenated with Array#join().
return html + '...' + arr.join('') + '...'; // by using .then(), the promise returned by getSubMenu() will deliver whatever is returned here.
});
}
在全 :
var url = "/_api/lists/getbytitle('GlobalTopNavMenu')/items?$select=Id,Title,Image,hasSubMenu,Link&$filter=Location eq 'GlobalNavigation'";
$.ajax({
url: url,
method: "GET",
headers: {
"Accept": "application/json; odata=verbose"
}
}).then(function(data) {
var promises = data.d.results.map(function(item) {
if (item.hasSubMenu == 'Yes') {
return getSubMenu(item.Id).then(function(subMenu) {
return '<li class="dropdown yamm-fw borderLeftY"><a href="#" title="" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">' + Res[item.Title] + '<b class="caret"></b></a>' + subMenu + '<dl class=""><dd class="picHolder"><img alt="" src="/PublishingImages/' + item.Image + '"/></dd></dl></div></div></li></ul></li>';
});
} else {
return '<li class="yamm-fw borderLeftY"><a href=#"' + item.Link + '" title="" class="dropdown-toggle" role="link" aria-haspopup="true" aria-expanded="false">' + Res[item.Title] + '</a></li>';
}
});
return $.when.apply(null, promises).then(function() {
$("#navbar").html('<ul class="nav navbar-nav nav-topmrgn">' + Array.prototype.join.call(arguments, '') + '</ul>');
});
});
function getSubMenu(id) {
var url = "/_api/lists/getbytitle('GlobalSubNavMenu')/items?$select=Id,Title,Link,ParentMenu/Id,root&$filter=ParentMenu/Id eq " + id + "&$expand=ParentMenu/Id";
return $.ajax({
url: url,
method: 'GET',
headers: {
'Accept': 'application/json; odata=verbose'
}
}).then(function(data) {
var html = (data.d.results.length < 6) ? '<ul class="dropdown-menu width500 spaceLeft">' : '<ul class="dropdown-menu width800 spaceLeft">';
html += '<li><div class="yamm-content"><div class="row">';
var arr = data.d.results.map(function(item) {
return '<dd class=""><a href=/' + (item.root ? '' : lang) + item.Link + '>' + Res[item.Title] + '</a></dd>';
});
return html + '<dl class="col-sm-3 mega-menu colborderRight">' + arr.join('') + '</dl>';
});
}