2014-09-04 2 views
0

Я запрашиваю некоторые данные из Firebase, используя AngularFire, как показано ниже.

$rootScope.userTags = $firebase($fbCurrent.child('tags')).$asArray();

На входе эти данные следующими способами я получаю выходы, как на изображении ниже. Так,

console.log($rootScope.userTags); 
console.log($rootScope.userTags[0]); 
$rootScope.userTags.$loaded().then(function() { 
    console.log($rootScope.userTags[0]); 
}); 

enter image description here

В первом заявлении журнала вы можете заметить $FirebaseArray объект с пятью элементами. Во втором заявлении журнала, когда я пытаюсь получить доступ к одному из элементов, я получаю undefined, хотя вы можете четко видеть эти элементы в массиве un $loaded. Теперь в последнем операторе журнала вызов $loaded позволяет мне обращаться к этим элементам без каких-либо проблем.

Почему он ведет себя так? И есть ли способ доступа к этим элементам, поскольку они уже существуют, не вызывая $loaded в массиве?

+1

Как правило, просто настройте такую ​​директиву, как 'ng-repeat', чтобы напечатать содержимое в вашем представлении, отбросить объект в $ scope и позволить Angular беспокоиться о том, когда он загружается. Это своего рода точка синхронизированных объектов и привязок. Если вы хотите манипулировать данными в своем контроллере, чего вы, вероятно, не должны делать, то вам нужно дождаться его загрузки. Если вы пытаетесь преобразовать данные с сервера, используйте $ extendFactory, как описано в документах, и снова, не беспокойтесь о том, когда он загружается. – Kato

ответ

2

Методы $asArray() или $asObject() являются асинхронными действиями. Данные должны быть загружены из Firebase, прежде чем они будут доступны. Это просто характер асинхронных данных, а не что-то особенное для Firebase.

Способ, которым мы справляемся с этой проблемой асинхронности, заключается в обещании $loaded.

Похоже, что настоящая проблема при обеспечении данных загружается при создании контроллера. Вы можете решить это, чтобы разрешить данные в маршрутизаторе.

Устранение требует обещания вернуть. Когда пользователь направляется на эту страницу, Angular не загружает страницу до тех пор, пока обещание не будет разрешено. Данные, разрешенные из обещания, будут введены в контроллер.

.config(['$routeProvider', 
    function($routeProvider) { 
    $routeProvider 

     .when('/resolve', { 
     templateUrl: 'resolve.html', 
     controller: 'ResolveCtrl', 

     resolve: { 
      // data will be injected into the ResolveCtrl 
      data: function($firebase) { 
      // resolve requires us to return a promise 
      return $firebase(new Firebase('your-firebase')).$asArray().$loaded(); 
      } 
     } 

     }) 
    } 
]) 

Теперь, когда мы решаем данные на маршруте, мы можем получить к нему доступ в нашем контроллере.

.controller('ResolveCtrl', function($scope, data) { 

    $scope.userTags = data; 
    $scope.userTags[0]; // data has been resolved from the promise 

}); 
+2

Отличный ответ на конкретный вопрос, но я считаю важным отметить, что во многих случаях, когда даже было бы интересно, загружаются ли данные, это потому, что они тратят усилия и энергию, изменяя данные в контроллере, вместо использования $ extendFactory или просто помещая данные в $ scope и позволяя виду заботиться о рендеринге. – Kato