Angularjs 如何使用resolve将firebase数据返回到$scope

Angularjs 如何使用resolve将firebase数据返回到$scope,angularjs,firebase,Angularjs,Firebase,我使用一项服务从firebase获取数据: 'use strict'; angular.module('flbi.services.trainings', []) .factory('trainingsService', ['FBURL', function(FBURL) { return { getList: function() { var queryLimit = 1

我使用一项服务从firebase获取数据:

'use strict';

angular.module('flbi.services.trainings', [])
    .factory('trainingsService', ['FBURL',
        function(FBURL) {
            return {
                getList: function() {

                    var queryLimit = 10;
                    var firebase = new Firebase(FBURL);

                    firebase.child('trainings').limit(queryLimit).on('value', function(trainings) {

                        var allTrainings = trainings.val();

                        $.each(allTrainings, function(training) {

                            firebase.child('users/' + allTrainings[training].userid).on('value', function(user) {

                                allTrainings[training].user = user.val();
                                allTrainings[training].user.gravatar = MD5(allTrainings[training].user.email);
                            });

                        });
                    });
                }
            };
        }]);
函数getList()是从以下位置调用的:

$routeProvider
            .when('/', {
                controller: 'trainingsCtrl',
                templateUrl: 'views/default.html',
                resolve: {
                    "trainings": function(trainingsService) {
                        return trainingsService.getList();
                    }
                }
            })
以及控制器:

'use strict';

angular.module('flbi.controllers.trainings', ['flbi.services.trainings'])
    .controller('trainingsCtrl', ['$scope', 'trainings',
        function($scope, trainings) {

            console.log(trainings); <-- just empty ....
            $scope.trainings = trainings;
        }]);
“严格使用”;
角度模块('flbi.controllers.trainings',['flbi.services.trainings']))
.controller('trainingsCtrl',['$scope','trainings',
职能(范围、培训){

console.log(trainings);您的resolve方法必须返回一个承诺才能按预期工作。所以您的getList方法应该返回一个承诺

另外,与使用.val()相比,更喜欢使用snapshot.forEach(),因为这是高度优化的(它迭代指针,而不是将所有数据解析和收集到一个对象中,它还对记录进行排序以匹配数据,因为JavaScript对象本身是无序的)


我试图在getList()方法中的任何地方都放上一个“return”…返回Firebase(或任何基于web的后端)的任何内容最后是一个异步调用。
getList
中的代码执行完毕后,数据可能还没有从Firebase返回。请看。有什么原因不使用AngularFire吗?这解决了Firebase和Angular之间的大部分同步问题。嘿!谢谢,这很有效!但有一点缺陷…我向您展示了它如果我第一次在页面上看到一个空白页面,但是如果我转到另一个页面(例如kontakt.html)并返回default.html,数据就会显示出来……你可能需要在$q.when()中添加一个$timeout。然后(…)调用wrap def.resolve()。我认为调用resolve()时会出现这种情况,但可能不会。
angular.module('flbi.services.trainings', [])
.factory('trainingsService', ['FBURL', '$q',
  function(FBURL, $q) {
    return {
      getList: function() {
        var def = $q.defer();

        var queryLimit = 10;
        var firebase = new Firebase(FBURL);

        firebase.child('trainings').limit(queryLimit).on('value', function(trainings) {
          var promises = [];
          var allTrainings = {};
          trainings.forEach(function(ss) {
            var key = ss.name();
            var d = $q.defer();
            promises.push(d.promise);
            // put any other data you need in the trainings keys here
            // allTrainings[key].widget = ss.child('widget').val();
            firebase.child('users/' + allTrainings[key].userid).on('value', function(user) {

              allTrainings[key].user = user.val();
              var email = user.child('email').val();
              allTrainings[key].user.gravatar = MD5(email);
              d.resolve();
            }, d.reject);
            $q.when(promises).then(function() {
              def.resolve(allTrainings);
            }, def.reject);
          });
        }, def.reject);

      return def.promise;
      }
    };
  }
]);