2016-11-02 6 views
2

SharePointでユーザーのサブWebのサブWebを受信しようとしました。 サブWebを受け取るための最初の呼び出し(関数getSubWebs())はすべて問題ありません。サブWebが受信され、それらを反復処理できます。getEnumerationのSECOND呼び出しでコレクションが初期化されていません。

しかし、私は同じ種類のコードを使ってそれらのウェブのサブウェブを取得しようとしています。 var webSubEnumerator = subwebCollection.getEnumerator(); )(私はロードを使用していてもエラーに

The collection has not been initialized 

を投げる前と(単にウェブ親要求に好き)ExecuteQueryAsyncの「成功」-partの内側にあるされています。

ここで問題が発生する可能性はありますか?

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を強制する方法よりも何もありません。

関連する問題