2014-01-18 4 views
1

Я построил эту заводскую службу:Угловая Service/Factory неопределенной ошибка

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 запускает цикл дайджеста после выполнения обработчиков выполнения/отклонения обещания , –

Смежные вопросы