Open hjzheng opened 8 years ago
$timeout 虽然是一个解决方案,但是它更像 hack 而不是 resolve,这里应该用 $scope.$$postDigest(fn)
来添加 dirty-check done hook,虽然是私有 api 但是方案上更 语义 & 贴近问题本质。
通常情况下在 ng 里要用到这个手段都是万不得已的情况,不建议当作合理场景,你可以从代码设计上再去考虑有没有更合理的方案。
@kuitos 👍 之后 AngularJS1.x 会添加方法$postDigestWatch https://github.com/angular/angular.js/issues/5828 去专门处理这种情况吧!
今天 Fix bug 遇到一个典型的问题, 先简单描述一下该问题:
参看上面的例子,其实我们是想得到中间 div 隐藏后,最后一个 div 的 offsetTop, 实际上得到的是中间 div 隐藏前的 offsetTop。
为什么呢,因为实际 toggle 中变量的变化,还没有引起 dom 变化,也就是脏检查并没有结束,Dom 也没有重新渲染。此时拿到的 offsetTop 肯定不是我们想要的。
可以参看此图:
那么怎么办呢,大家都知道 js 是单线程的,存在一个 event loop 来处理异步任务,这些异步任务存放在一个队列里, 所以我们只需要将获取 offsetTop 操作放入这个队列里就 OK。 当 ng-click 中的函数,AngularJS的脏检查等如上图所示 在队列中执行完毕后,就轮到我们的获取 offsetTop 的异步任务了。
很简单
参考资料: https://docs.angularjs.org/guide/scope http://www.ruanyifeng.com/blog/2014/10/event-loop.html http://notes.iissnan.com/2014/waiting-for-dom-to-finish-rendering/