【发布时间】:2014-11-17 21:45:14
【问题描述】:
我有一个在 1.2.25 版本之上构建的相对较大的 Angular 应用程序。在我最近升级到 1.3.0 的过程中,我发现只有一个主要问题在对 DOM 进行 html 类更改时似乎发生了变化。
在这个 jsfiddle 示例中,请注意获取 DOM 元素大小的手表,它基于另一个指令更改的类: http://jsfiddle.net/travisgosselin/sx7jponj/1/ 此示例使用 Angular 1.2.25。
scope.$watch(function () {
return {
width: element.closest('.checkSize').width(),
height: element.closest('.checkSize').height()
};
}, function (size) {
scope.height = size.height;
}, true);
另一个完全相同但使用 Angular 1.3.0 的 jsfiddle,您会注意到 watch 不会触发更新,因为在 $watch 发生之后似乎应用了该类,因此不会更新元素的大小. http://jsfiddle.net/travisgosselin/t80segou/1/
scope.$watch(function () {
return {
width: element.closest('.checkSize').width(),
height: element.closest('.checkSize').height()
};
}, function (size) {
scope.height = size.height;
}, true);
这背后的想法是允许我的一个指令独立于另一个组件中发生的事情来调整大小。
在 Angular 更改日志中,我能看到的唯一轻微相关的更改是与 ngAnimate 相关的更改。请参阅 1.3.0-rc.5 下的重大更改: $animate CSS 类 API 将始终将更改推迟到下一个摘要结束。这允许 ngAnimate 将在短时间内发生的类更改合并为 1 或 2 次 DOM 写入,而不是多次。这可以防止 IE 等浏览器出现卡顿,通常是一件好事。 如果你发现你的类没有被立即应用,一定要调用 $digest()。
知道如何最好地修改此场景以触发 dom 元素大小的手表吗?在这一点上,我唯一的选择是使用从许多不同位置触发的一系列事件,这些事件会强制调整大小(发布/订阅)。
【问题讨论】:
-
您可以在调用
changeSize()时触发一个摘要循环。最后添加一个$timeout();电话。是的,我知道,那很脏…… -
感谢黑洞的建议。 Angular 中的所有解决方法似乎都以“$timeout”开头。我确实在我的应用程序中尝试过,它运行良好 - 但是你必须将一个函数传递给 $timeout 否则它会出错 - 所以我不得不传递一个空函数,使它更加丑陋。话虽如此,它是如此简单,我用它来解决很多 cmets。我真的很想了解如何在 Angular 中解决这种情况,或者这里是否存在错误(我想理想情况下,我不应该根据元素大小在指令中构建我的手表)。
-
我还看到 ng-class 具有竞争条件并最终将旧值和新值都应用于 dom 的情况,而应该只应用一个类。