2014-01-18 32 views
1

我建這個廠服務:角服務/工廠未定義的錯誤

spApp.factory('siteCollection', function(){ 
    return { 
    usersObject : [], 
    getUsers : function(){ 
     $().SPServices({ 
     operation: "GetUserCollectionFromSite", 
     completefunc: function(xData, Status) { 
      var responseXML = $(xData.responseXML); 
      responseXML.find("User").each(function() { 
      usersObject.push({ 
       id: $(this).attr("ID"), 
       name: $(this).attr("Name"), 
       domainAccount: $(this).attr("LoginName") 
      }); 
      }); 
     } 
     }); 
     return usersObject; 
    } 
    } 
}) 

它想回到我在頂部聲明,但控制檯是給我的對象未定義錯誤的usersObject。

這是控制器:

spApp.controller('userCtrl', 
    function userCtrl($scope,siteCollection){ 
     $scope.users = siteCollection.getUsers(); 
    } 
); 

我很新的角度。

回答

0

它應該是這樣的

spApp.factory('siteCollection', function(){ 
    var usersObject = []; 
    return { 
    getUsers : function(){... 

你回報的方法來訪問數據的對象,但他們在範圍無關。所以如果你只在返回對象中定義usersObject,那麼它在getUsers中是不可訪問的。

3

有兩個問題與您的代碼:

第一:你的工廠返回與性能usersObject和getUsers,一個對象,但在getUsers您嘗試訪問變量「usersObject」(這是不是返回對象的屬性)。你必須聲明變量外:

var usersObject = []; 
return { 
    getUsers: function() { 
    // ... 
    return usersObject; 
    } 
}; 

第二:您填寫在異步調用回調函數你usersObject。 AngularJS不會在您的數組中註冊更改。您可以使用$ rootScope。$ apply(),然後AngularJS將運行摘要並在新數據添加到數組之後更新視圖。

spApp.factory('siteCollection', function ($rootScope) { 
    // ... 
    $rootScope.$apply(function() { 
    responseXML.find("User").each(function() { ... }); 
    }); 
} 

使用$ rootScope。$ apply()不是很乾淨。更好的辦法是返回一個承諾:

spApp.factory('siteCollection', function ($q) { 
    return { 
    getUsers : function(){ 
     var deferred = $q.defer(); 

     $().SPServices({ 
     operation: "GetUserCollectionFromSite", 
     completefunc: function(xData, Status) { 
      var responseXML = $(xData.responseXML), 
       usersObject = []; 

      responseXML.find("User").each(function() { 
      usersObject.push({ 
       id: $(this).attr("ID"), 
       name: $(this).attr("Name"), 
       domainAccount: $(this).attr("LoginName") 
      }); 
      }); 

      deferred.resolve(usersObject); 
     } 
     }); 

     return deferred; 
    } 
    } 
}); 

如果你決定使用承諾,將它添加到你的控制器做一些數據已經被加載後:

siteCollection.getUsers.then(function (users) { 
    // ... 
}); 
+0

嘿第一期改問題。但是,我並不真正瞭解這裏的承諾需求。我正在使用ng-repeat,它似乎在工作。承諾如何提供幫助?謝謝。 – Batman

+1

使用外部庫(jQuery/SPServices)從服務器加載數據。當這個進程異步運行時(並且我希望這樣做)腳本會繼續運行,並且只要數據加載完成,就會執行回調。但是Angular不知道這個過程何時結束,因此它不會執行摘要循環,不會執行監視,更新視圖等。當您使用承諾時,在承諾的執行/拒絕處理程序執行後,Angular運行一個摘要循環。 –