为什么 Angular 没有在这里更新范围? [英] How come Angular doesn't update with scope here?
问题描述
我对 Angular 还很陌生,我使用 firebase 作为我的后端.我希望有人可以调试这个问题.当我第一次访问我的页面 www.mywebsite.com/#defaultHash 时,数据不会加载到 DOM 中,而是在访问另一个哈希链接并返回后加载.
I'm pretty new to Angular and I'm using firebase as my backend. I was hoping someone could debug this issue. When I first go to my page www.mywebsite.com/#defaultHash the data doesn't load into the DOM, it does after visiting another hash link and coming back though.
我的控制器是这样的:
/* initialize data */
var fb = new Firebase('https://asdf.firebaseio.com/');
/* set data to automatically update on change */
fb.on('value', function(snapshot) {
var data = snapshot.val();
$scope.propertyConfiguration = data.products;
console.log($scope.propertyConfiguration);
console.log("Data retrieved");
});
/* save data on button submit */
$scope.saveConfigs = function(){
var setFBref = new Firebase('https://asdf.firebaseio.com/products');
setFBref.update($scope.propertyConfiguration);
console.log("configurations saved!");
};
我有 3 条散列路由,分别是Shared"、Registration"和Home",而 else.redirectTo 设置为Shared".(他们都使用这个控制器)这是发生的错误:(所有链接"都是href="#hashWhereever")
I have 3 hash routes say "Shared", "Registration", and "Home" with otherwise.redirectTo set to "Shared".(They all use this controller) Here's the error that occurs: (all "links" are href="#hashWhereever")
1) 转到 website.com/#Shared 或直接刷新.控制台记录 $scope.propertyConfiguration 和数据检索".DOM 什么也没显示.
1) Go to website.com/#Shared or just refresh. Console logs $scope.propertyConfiguration and "Data Retrieved". DOM shows nothing.
2) 点击website.com/#Registration,控制台正确记录$scope数据,DOM正确加载.
2) Click to website.com/#Registration, console logs $scope data properly, DOM is loaded correctly.
3) 点击返回 website.com/#Shared,控制台正确记录 $scope 数据,但这次 DOM 正确加载.
3) Click back to website.com/#Shared, console logs $scope data properly yet this time DOM loads correctly.
4) 刷新当前正确加载的 website.com/#Shared.DOM 元素消失.
4) Refresh currently correctly loaded website.com/#Shared. DOM elements disappear.
既然 $scope.data 在这里的所有情况下都是正确的,Angular 不应该确保 DOM 正确反映模型吗?为什么只有当我从另一个链接单击页面时 DOM 才能正确加载.
Since $scope.data is correct in all the cases here, shouldn't Angular make sure the DOM reflects the model properly? Why is it that the DOM loads correctly only when I am clicking to the page from another link.
我可以通过添加 window.location.hash = "Shared" 来修复"它,但它会在控制台中引发大量错误.
I can "fix" it by adding window.location.hash = "Shared" but it throws a huge amount of errors in the console.
已修复:(有点)
函数 $scope.$apply() 强制视图与模型同步.我会自己回答这个问题并关闭它,但我仍然想知道为什么当我正确地为 $scope 分配一个值时视图没有正确加载.如果 Angular 的脏检查"在模型有可能发生变化时进行检查,那么为 $scope 分配一个值不会过分吗?
The function $scope.$apply() forces the view to sync with the model. I'd answer this question myself and close it but I'm still wondering why the view doesn't load correctly when I correctly assign a value to $scope. If Angular's "dirty checking" checks whenever there is a possibility the model has changed, doesn't assigning a value to $scope overqualify?
推荐答案
Angular 无法知道您已为 $scope.variable 赋值.这里没有魔法.当您运行指令 (ng-click/ng-submit) 或 Angular 内部函数时,它们都会调用 $apply() 并触发摘要(检查脏标志和更新例程).
Angular has no way to know you've assigned a value to $scope.variable. There's no magic here. When you run a directive (ng-click/ng-submit) or Angular internal functions, they all call $apply() and trigger a digest (a check of the dirty flags and update routine).
一种可能比 $apply 更安全的方法是使用 $timeout.目前,如果您在 Firebase 中调用写入操作,它可以同步触发事件侦听器(child_ added、child_changed、value 等).这可能会导致您在 $apply 范围内调用 $apply .如果这样做,则会引发错误.$timeout 绕过了这个.
A possibly safer approach than $apply would be to use $timeout. Currently, if you call a write op in Firebase, it could synchronously trigger an event listener (child_added, child_changed, value, etc). This could cause you to call $apply while still within a $apply scope. If you do this, an Error is thrown. $timeout bypasses this.
请参阅此 SO 问题,了解有关该主题的更多信息摘要和 $timeout.
See this SO Question for a bit more on the topic of digest and $timeout.
Angular 开发人员指南中的此文档介绍了编译的工作原理;非常适合任何认真的 Angular 开发者阅读的背景知识.
This doc in the Angular Developer Guide covers how compile works; very great background read for any serious Angular dev.
此外,您可以通过使用 Angular 的官方 Firebase 绑定来为自己节省大量精力,它已经考虑了所有这些实现细节.
Also, you can save yourself a good deal of energy by using the official Firebase bindings for Angular, which already take all of these implementation details into account.
相关注意事项:在不久的将来,Angular 将能够利用 Object.observe 魔法 来处理这些更新.
Vaguely Related Note: In the not-too-distant future, Angular will be able to take advantage of Object.observe magic to handle these updates.
这篇关于为什么 Angular 没有在这里更新范围?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!