问题

数据绑定在 AngularJS 框架中如何工作?

我没有找到有关其网站的技术详细信息.当数据从视图传播到模型时,它是或多或少地清楚如何工作.但是AngularJS如何跟踪模型属性的变化,没有setters和getter?

我发现有 JavaScript观察器可以执行此操作.但是在 Internet Explorer 6 Internet Explorer 7 .那么AngularJS如何知道我改变了例如下面的内容并在视图上反映了这个变化?

myobject.myproperty="new value";


解决方法

AngularJS记住值并将其与先前的值进行比较.这是基本的脏检查.如果值发生更改,则会触发更改事件.

$ apply()方法是从非AngularJS世界过渡到AngularJS世界时调用的方法,调用 $ digest().摘要只是普通的旧脏检查.它适用于所有浏览器,完全可预测.

要比较脏检查(AngularJS)与变更监听器( KnockoutJS Backbone.js ):虽然脏检查可能看起来很简单,甚至效率低下(我会在后面谈到),但事实证明它在语义上是正确的所有时间,而变化的侦听器有很多奇怪的角落情况,需要像依赖关系跟踪,以使它更语义正确. KnockoutJS依赖关系跟踪是AngularJS没有的问题的一个聪明的功能.

Issues with change listeners:

  • The syntax is atrocious, since browsers do not support it natively. Yes, there are proxies, but they are not semantically correct in all cases, and of course there are no proxies on old browsers. The bottom line is that dirty-checking allows you to do POJO, whereas KnockoutJS and Backbone.js force you to inherit from their classes, and access your data through accessors.
  • Change coalescence. Suppose you have an array of items. Say you want to add items into an array, as you are looping to add, each time you add you are firing events on change, which is rendering the UI. This is very bad for performance. What you want is to update the UI only once, at the end. The change events are too fine-grained.
  • Change listeners fire immediately on a setter, which is a problem, since the change listener can further change data, which fires more change events. This is bad since on your stack you may have several change events happening at once. Suppose you have two arrays which need to be kept in sync for whatever reason. You can only add to one or the other, but each time you add you fire a change event, which now has an inconsistent view of the world. This is a very similar problem to thread locking, which JavaScript avoids since each callback executes exclusively and to completion. Change events break this since setters can have far-reaching consequences which are not intended and non obvious, which creates the thread problem all over again. It turns out that what you want to do is to delay the listener execution, and guarantee, that only one listener runs at a time, hence any code is free to change data, and it knows that no other code runs while it is doing so.

What about performance?

所以看起来我们很慢,因为脏检查是低效的.这是我们需要查看实数而不仅仅是理论参数,但首先让我们定义一些约束.

人类是:

  • Slow _ Anything faster than 50 ms is imperceptible to humans and thus can be considered as "instant".

  • Limited _ You can't really show more than about 2000 pieces of information to a human on a single page. Anything more than that is really bad UI, and humans can't process this anyway.

所以真正的问题是:你可以在50毫秒内在浏览器上做多少比较?这是一个难以回答的问题,许多因素都会发挥作用,但这里是一个测试用例: http://jsperf.com/angularjs -digest / 6 ,创建10,000个观察者.在现代浏览器上,这只需要不到6毫秒.在 Internet Explorer 8 上,大约需要40 ms.正如你可以看到,这不是一个问题,即使在缓慢的浏览器这些天.有一个警告:比较需要是简单的适应时间限制...不幸的是,它是太容易添加一个慢的比较到AngularJS,所以很容易构建缓慢的应用程序,当你不知道什么是做.但是我们希望通过提供一个仪器模块来得到答案,这将显示哪些是慢速比较.

事实证明,视频游戏和GPU使用脏检查方法,特别是因为它是一致的.只要他们超过了显示器的刷新频率(通常是50-60 Hz,或每16.6-20 ms),任何性能都是一种浪费,所以你最好是绘制更多的东西,而不是FPS更高. p>




相关问题推荐