我正在使用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绑定。
任何人都能解释一下吗?我做错了吗?
答案 0 :(得分:2)
因为您在AngularJS之外更改了范围,所以必须使用$ scope。$ apply()来通知Angular范围更改。这是处理这种情况的常用方法。要使用AngularJS的错误处理,我会将代码包装在回调函数中,如:
$scope.$apply(function(){
$scope.tools.push(snapshot.val());
});
答案 1 :(得分:1)
我不确定Firebase once
方法是如何工作的,但似乎它在回调中对Angular上下文之外的模型进行了更改,因此您需要$scope.$apply
。
在$http
,$resource
和$timeout
这样的内部服务内部调用$scope.$apply
,这样您就无需在回调中调用它。如果Firebase
系统为内部确实应用或返回承诺的once
提供方法替换,则可以一次又一次跳过调用apply
方法。
答案 2 :(得分: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());
})
});
答案 3 :(得分:0)
要在更改范围时更新范围,您需要使用angularFire的工厂angularFireCollection
。否则,您只是调用一个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());
});
};