2017-05-01 32 views
0

我從兩個rest api創建動態菜單。菜單將由父母/子女關係創建。這意味着父ajax響應的id將傳遞給子ajax來獲取子記錄。根據對方調用兩個ajax調用,但沒有異步

問題是當我使用async false爲我的孩子AJAX調用我的網站變得緩慢,當我刪除它比我的菜單不呈現。一些幫助。

我的代碼調用父

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; 
} 

如果我刪除從子功能異步假比菜單將不會呈現。那我該怎麼做。

+0

也許這? http://api.jquery.com/jQuery.when/ –

+0

請問你可以幫助我的ajax – Milind

回答

1

隨着async: falsegetSubMenu()是 - 異步,因此,

  • getSubMenu()必須返回一個承諾(良好做法)或接受回調(不好的做法),這取決於從獲得的數據
  • 代碼getSubMenu()必須作相應的分解。

這不是最簡單的使用異步派生數據的介紹,特別是因爲getSubMenu()是從循環中調用的。

您需要了解以下信息:

  • jQuery.ajax()返回一個承諾,讓您鏈.then()。在解決這個問題時,您將從.then()的額外功率中獲得巨大收益,而不是「成功:」回調。
  • Array#map()將數組映射到任何您喜歡的新數組。這裏Array#map()在創建由getSubMenu()返回的承諾數組時特別有用。
  • jQuery.when()彙總多個承諾並返回單個承諾。

這裏有一個鏤空的圖案,將解決你的問題:

$.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>'; 
    }); 
} 
+0

讓我試試並找回你\ – Milind

+0

你的代碼沒有給出任何錯誤,但它是未定義的。我認爲我們沒有評估變量 – Milind

+0

嗨解決這個問題,它是流利的工作。我愛你。但我喜歡你編輯你的代碼時,你映射第一個參數是項目,另一個是索引,所以你必須改變這兩個函數。另一個從getSubMenu刪除異步:false – Milind

0

您可以通過修改功能位,如下

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) { 
    var totalMenus = data.d.results.length; 
    $.each(data.d.results, function(i, item) { 
     getSubMenu(item, function (submenuMarkup) { 
      html += submenuMarkup; 
      if (totalMenus === (i+1)) { 
       html += "</ul>"; 
       $("#navbar").empty(); 
       $("#navbar").append(html); 
      } 
     }); 
    }); 
    } 
}); 

getSubMenu會有一個回調函數作爲PARAM,並返回產生submenumarkup。

function getSubMenu(mainItem, cb) { 
    var subMenuMarkup = ""; 
    var innerSubMenuMarkup = ""; 

    if (!(mainItem.hasSubMenu == "Yes")) { 
    subMenuMarkup = "<li class='yamm-fw borderLeftY'><a href='" + mainItem.Link + "' title='' class='dropdown-toggle' role='link' aria-haspopup='true' aria-expanded='false'>" + Res[mainItem.Title] + "</a></li>"; 
    cb(subMenuMarkup); 
    return; 
    } 


    var url = "/_api/lists/getbytitle('GlobalSubNavMenu')/items?$select=Id,Title,Link,ParentMenu/Id,root&$filter=ParentMenu/Id eq " + mainItem.Id + "&$expand=ParentMenu/Id"; 

    $.ajax({ 
    url: url, 
    method: "GET", 
    headers: { 
     "Accept": "application/json; odata=verbose" 
    }, 
    success: function(data) { 
     if (data.d.results.length < 6) 
     innerSubMenuMarkup += "<ul class='dropdown-menu width500 spaceLeft'>"; // 
     else 
     innerSubMenuMarkup += "<ul class='dropdown-menu width800 spaceLeft'>"; 

     innerSubMenuMarkup += "<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) 
      innerSubMenuMarkup += "</dl><dl class='col-sm-3 mega-menu colborderRight'><dd class=''><a href=/" + (item.root ? "" : lang) + item.Link + ">" + Res[item.Title] + "</a></dd>"; 
     else 
      innerSubMenuMarkup += "<dd class=''><a href=/" + (item.root ? "" : lang) + item.Link + ">" + Res[item.Title] + "</a></dd>"; 
     }); 

     subMenuMarkup += "<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>"; 
     subMenuMarkup += innerSubMenuMarkup + "</dl>"; 
     subMenuMarkup += "<dl class=''><dd class='picHolder'><img alt='' src='/PublishingImages/" + item.Image + "'/></dd></dl></div></div></li></ul></li>"; 
     cb(subMenuMarkup); 
    } 
    }); 
} 
+0

謝謝你從哪裏得到的答覆'id'它是undefined – Milind

+0

我錯過了將id更新爲mainItem。 ID。對不起。現在試試。 – HumbleGeek

+0

還有問題項目部分未解決Res [item。標題]它給出了錯誤 – Milind