角度服务/工厂未定义错误

时间:2014-01-18 02:34:32

标签: javascript angularjs angular-services

我建立了这个工厂服务:

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

我对Angular很新。

2 个答案:

答案 0 :(得分: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;
    }
  }
});

如果您决定使用promises,请将其添加到控制器中,以便在加载数据后执行某些操作:

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

答案 1 :(得分:0)

看起来应该是这样的

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

您的返回是访问数据的方法的对象,但它们的范围不相关。因此,如果您只在返回对象中定义usersObject,则无法在getUsers中访问它。