该集合尚未在第二次调用getEnumeration时初始化

时间:2016-11-02 12:45:37

标签: javascript jquery sharepoint

我尝试在SharePoint中接收用户子网站的子网站。 在第一次接收子网站的调用(函数getSubWebs())一切都很好:接收子网站,我可以遍历它们。

然而,当我尝试使用相同类型的代码获取这些网站的子网站时 var webSubEnumerator = subwebCollection.getEnumerator();抛出错误

The collection has not been initialized

即使我之前使用过Load()并且在ExecuteQueryAsync的“成功”部分内部(就像在web父请求上一样)。

这会导致什么问题?

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().的Success()函数内部所以我相信这不是典型的“尝试在异常数据存在之前读取” - 问题

1 个答案:

答案 0 :(得分:1)

问题出现了,因为您在while循环中多次调用回调函数,并且回调函数从包含的范围引用变量(subwebCollection) - 意味着每次调用function访问包含函数作用域中定义的相同共享变量(以及相同的共享值)。

(与大多数编程语言不同,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模仿块级范围而不是其变量的函数级范围的方法。