0

我正在使用 AngularJS 和 angularFire 来显示我的任务列表:

<ul ng-repeat="tool in tools">
    <li>{{tool.name}} {{ tool.description}}</li>
</ul>

var toolRef = new Firebase(dbRef + "/tools/" + toolId);
toolRef.once('value', function(snapshot) {
      console.log(angular.toJson(snapshot.val()));
      $scope.tools.push(snapshot.val());
      //$scope.$apply();
});

http://jsfiddle.net/oburakevych/5n9mj/11/

代码非常简单:我将一个“站点”对象绑定到我的 Firebase 数据库。该对象包含相关工具的 ID 列表。然后我在 $scope.tools 变量中加载每个工具并使用 ng-repeat 在 UI 中显示它们。但是,每次我将新条目推送到我的 $scope.tools 时,DOM 都不会更新。我必须在每次推送后调用 $scope.$apply 来触发摘要 - 请参阅第 18 行的注释,然后它就可以工作了。

这真的很奇怪,因为我现在播了好几次,而且只使用与 angularFire 绑定的范围变量。

谁能解释一下?我做错什么了吗?

4

4 回答 4

2

我不确定 Firebaseonce方法是如何工作的,但它似乎在它的回调中对 Angular 上下文之外的模型进行更改,因此你需要$scope.$apply.

$http在、$resource$timeout内部调用等角度服务中$scope.$apply,您无需在回调中调用它。如果系统提供了一个内部确实应用或返回承诺Firebase的方法替换,您可以一次又一次地跳过对方法的调用。onceapply

于 2013-08-20T07:54:48.783 回答
2

因为您在 AngularJS 之外更改范围,所以您必须使用 $scope.$apply() 来通知 Angular 有关范围更改。这是处理它的常用方法。要使用 AngularJS 的错误处理,我会将代码包装在回调函数中,例如:

$scope.$apply(function(){
  $scope.tools.push(snapshot.val());
});
于 2013-08-20T07:56:30.900 回答
0

正如 tschiela 所说,您需要包装函数。我使用 $timeout。所以...

<ul ng-repeat="tool in tools">
    <li>{{tool.name}} {{ tool.description}}</li>
</ul>

var toolRef = new Firebase(dbRef + "/tools/" + toolId);
toolRef.once('value', function(snapshot) {
      $timeout(function() {
          $scope.tools.push(snapshot.val());
      })
});
于 2013-08-20T12:43:08.960 回答
0

要在更改范围时更新范围,您需要使用angularFireCollectionangularFire 的工厂。否则,您只是调用一个 javascript 类,直到$apply().

var getTool = function(dbRef,toolId) {
    console.log("Gettingtool ID: " + toolId);
    angularFireCollection(dbRef + "/tools/" + toolId, function(snapshot) {
          console.log(angular.toJson(snapshot.val()));
          $scope.tools.push(snapshot.val());
    });
};

演示

于 2013-08-20T16:42:21.473 回答