2016-11-02 99 views
2

我嘗試接收SharePoint中用戶子網站的子網站。 在第一次接收子網站(函數getSubWebs())時,一切正常:子網站已收到,我可以遍歷它們。該集合尚未初始化getEnumeration的第二個電話

但是我嘗試使用相同類型的代碼獲取這些網站的子網頁 var webSubEnumerator = subwebCollection.getEnumerator();之前引發錯誤

The collection has not been initialized 

即使我使用load()和是ExecuteQueryAsync的「成功」雙組分(就像在腹板父請求)內。

什麼可能導致問題在這裏?

var context = SP.ClientContext.get_current(); 
var user = context.get_web().get_currentUser(); 
var web = context.get_web(); 
var lists = web.get_lists(); 

var parrentwebCollection = null; 
ExecuteOrDelayUntilScriptLoaded(getSubWebs, "sp.js"); 

function getSubWebs(){ 
    parrentwebCollection = web.getSubwebsForCurrentUser(null); 
    context.load(parrentwebCollection) 
    context.executeQueryAsync(onGetSubwebsSuccess, onGetSubwebsFail); 
} 

function onGetSubwebsSuccess(sender, args){ 
    var webEnumerator = parrentwebCollection.getEnumerator(); 
    // Everything works FINE on this getEnumerator() 

    while (webEnumerator.moveNext()){ 
    var webParrent = webEnumerator.get_current(); 
    var parrenttitel = webParrent.get_title(); 
    var parrenturl = webParrent.get_url(); 

    //Load Subs From Parrent 
    var subwebCollection = null; 
    subwebCollection = webParrent.getSubwebsForCurrentUser(null); 

    if (subwebCollection != undefined && subwebCollection != null) { 
     context.load(subwebCollection); 
     context.executeQueryAsync(onGetSSubwebsSuccess, onGetSSubwebsFail); 

     function onGetSSubwebsSuccess(sender, args) { 
     console.log("getSubWebs query successful") 
     var webSubEnumerator = subwebCollection.getEnumerator(); 
     // THIS getEnumerator(), however throws an exception 

     while (webSubEnumerator.moveNext()){ 
      console.log("After While") 
      var subweb = webSubEnumerator.get_current(); 
      var subtitel = subweb.get_title(); 
     }    
     } 

     function onGetSSubwebsFail(sender, args){ 
     alert("Request to retrieve subwebs failed. Error: " + args.get_message()) 
     } 
    } 
    }    
} 

function onGetSubwebsFail(sender, args){ 
    alert("Request to retrieve subwebs failed. Error: " + args.get_message()) 
} 

請注意,我是成功的()內 - 的executeQueryAsync().功能,所以我相信這不是典型的「嘗試讀取異步數據之前,它是有」 - 問題

回答

1

由於您在while循環內多次調用回調函數,並且回調函數從包含範圍引用一個變量(subwebCollection),意味着函數的每次調用都訪問相同的共享包含函數範圍中定義的變量(因此也是相同的共享值)。

(不像大多數編程語言,JavaScript是功能範圍的,而不是塊作用域。)

您可以通過使用一個「封閉」 while循環內,以確保回調每次調用函數繞開的問題有對其需要的變量的本地副本的引用。

function onGetSubwebsSuccess(sender, args) { 
    var webEnumerator = parentwebCollection.getEnumerator(); 
    while (webEnumerator.moveNext()) { 
     var webparent = webEnumerator.get_current(); 
     var parenttitle = webparent.get_title(); 
     (function(){ /* anonymous function expression wraps the subwebCollection variable in a closure (creates a new scope for the variable) */ 
      var subwebCollection = null; 
      subwebCollection = webparent.getSubwebsForCurrentUser(null); 
      if (subwebCollection != undefined && subwebCollection != null) { 
       context.load(subwebCollection); 
       context.executeQueryAsync(onGetSSubwebsSuccess, onGetSSubwebsFail); 
       function onGetSSubwebsSuccess(sender, args) { 
        console.log("getSubWebs query successful") 
        var webSubEnumerator = subwebCollection.getEnumerator(); 
        while (webSubEnumerator.moveNext()) { 
         console.log("After While") 
         var subweb = webSubEnumerator.get_current(); 
         var subtitel = subweb.get_title(); 
        } 
       } 
       function onGetSSubwebsFail(sender, args) { 
        alert("Request to retrieve subwebs failed. Error: " + args.get_message()) 
       } 
      } 
     })(); /* we immediately invoke the function expression */ 
    } 
} 

該技術通常被稱爲立即調用函數表達式或IIFE。

(function(){ 
    // closure 
})(); 

這只不過是強制JavaScript模擬塊級作用域而不是其變量的函數級作用域範圍的方法。