【问题标题】:Firebase callbacks and AngularJSFirebase 回调和 AngularJS
【发布时间】:2012-10-15 10:43:00
【问题描述】:

我正在结合 Firebase 学习 AngularJS。我真的在努力处理 Firebase 的 on 回调并尝试更新 $scope...

$apply already in progress <----

    var chat = angular.module('chat', []);
   chat.factory('firebaseService', function ($rootScope) {
  var firebase = {};
  firebase = new Firebase("http://gamma.firebase.com/myUser");
  return {
    on: function (eventName, callback) {
      firebase.on(eventName, function () {  
        var args = arguments;
        $rootScope.$apply(function () {
          callback.apply(firebase, args);
        });
      });
    },
    add: function (data) {
      firebase.set(data);
    }
  };
});

chat.controller ('chat', function ($scope, firebaseService) {
    $scope.messages = [];
    $scope.username;
    $scope.usermessage;              
    firebaseService.on("child_added",function(data){        
        $scope.messages.push(data.val());       
    });
    $scope.PushMessage = function(){
        firebaseService.add({'username':$scope.username,'usermessage':$scope.usermessage});   
    };
});

如果我将$rootscope.$apply 取出,那么它会按预期工作,但不会在页面加载时更新 DOM。

谢谢!

更新

解决方案 1 - 删除服务上的 $rootscope.$apply 并将 $timeout 注入并应用到控制器:

firebaseService.on('child_added',function(data){        
    $timeout(function(){
        $scope.messages.push(data.val());                       
    },0);
});

解决方案 2 - 实施“SafeApply”方法(感谢Alex Vanston):

$scope.safeApply = function(fn) {
        var phase = this.$root.$$phase;
        if(phase == '$apply' || phase == '$digest') {
            fn();
        } else {
            this.$apply(fn);
        }
    };

虽然这些都可以工作并且代码不多,但我觉得它们太老套了。是不是有一些官方的 Angular 方式来处理异步回调?

我为类似情况找到的另一个很好的例子:HTML5Rocks - AngularJS and Socket.io

【问题讨论】:

  • Firebase 创始人在这里——这看起来更像是一个我只知道一点点的 Angular 问题。很抱歉没有提供更多帮助!未来我们希望有一些不错的参考示例,可能还有一个支持 Angular 的库。
  • 另外,您可能需要查看 Angular Google Group。那里已经有一些 Firebase 讨论,例如这个线程:groups.google.com/forum/#!topic/angular/sJzqb6UMVMQ
  • 很高兴收到您的来信!我将遵循该主题的建议,并尝试将 Firebase 保留为服务。期待您的示例并更多地使用 Firebase。谢谢!

标签: angularjs firebase


【解决方案1】:

解决方案 1 - 删除服务上的 $rootscope.$apply 并将 $timeout 注入并应用到控制器:

firebaseService.on('child_added',function(data){        
    $timeout(function(){
        $scope.messages.push(data.val());                       
    },0);
});

解决方案 2 - 实施“SafeApply”方法(感谢 Alex Vanston):

$scope.safeApply = function(fn) {
        var phase = this.$root.$$phase;
        if(phase == '$apply' || phase == '$digest') {
            fn();
        } else {
            this.$apply(fn);
        }
    };

【讨论】:

  • 我喜欢这个解决方案,但是我正在做一个调整。在调用 fn() 之前,请确保它不为 null 或未定义。如果 (fn) { fn(); }
  • 检查相位值让我很紧张。我会非常小心地使用这种方法。我想知道这是否是使用 $scope.$evalAsync() 的好时机(我不时在需要 $timeout 的事件侦听器上使用它)。
猜你喜欢
  • 1970-01-01
  • 2013-09-06
  • 1970-01-01
  • 2013-07-22
  • 1970-01-01
  • 2016-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多