一尘不染

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

javascript

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

我尚未在其网站上找到技术细节。数据从视图传播到模型时,或多或少地清楚了它是如何工作的。但是,AngularJS如何在没有设置者和获取者的情况下跟踪模型属性的变化?

我发现有些JavaScript观察程序可以完成这项工作。但是Internet Explorer 6和Internet Explorer 7不支持它们。那么AngularJS如何知道我更改了以下内容并在视图中反映了此更改?

myobject.myproperty="new value";

阅读 304

收藏
2020-04-23

共1个答案

一尘不染

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

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

对比脏检查(AngularJS)与更改侦听器(KnockoutJS和Backbone.js):尽管脏检查似乎很简单,甚至效率很低(我稍后会解决),但事实证明,它一直在语义上是正确的,变更侦听器有很多奇怪的极端情况,并且需要诸如依赖性跟踪之类的东西才能使其在语义上更加正确。KnockoutJS依赖项跟踪是AngularJS所没有的问题的一项聪明功能。

变更侦听器的问题:

  • 该语法非常糟糕,因为浏览器本身不支持它。是的,有代理,但是在所有情况下它们在语义上都不正确,当然,在旧的浏览器上也没有代理。最重要的是,脏检查允许你执行POJO,而KnockoutJS和Backbone.js迫使你从其类继承,并通过访问器访问数据。
  • 更改合并。假设你有一组项目。假设你要在添加循环时将项目添加到数组中,每次添加时,你都会触发更改事件,即呈现UI的事件。这对性能非常不利。你想要的是最后只更新一次UI。更改事件的粒度太细。
  • 更改侦听器会立即在设置器上触发,这是一个问题,因为更改侦听器可以进一步更改数据,从而触发更多的更改事件。这很不好,因为在你的堆栈上,你可能同时发生多个更改事件。假设你有两个数组,无论出于何种原因都需要使它们保持同步。你只能添加一个或另一个,但是每次添加时,都会触发一个更改事件,该事件现在对世界有不一致的看法。这与线程锁定非常相似,由于每个回调都专门执行并完成,因此JavaScript避免了线程锁定。更改事件打破了这一点,因为设置员可能会产生意想不到且不明显的深远后果,从而再次造成线程问题。事实证明,你想要做的是延迟侦听器的执行,并保证,

性能如何?

因此,由于脏检查效率低下,因此我们似乎很慢。这是我们需要查看实数而不是仅具有理论参数的地方,但是首先让我们定义一些约束。

人类是:

  • 慢 -任何比50毫秒都快的速度是人类所无法察觉的,因此可以视为“即时”。

  • 受限 -你在一个页面上不能真正显示超过2000条信息。除此之外,还真是糟糕的UI,人类无论如何都无法处理。

因此,真正的问题是:你可以在50毫秒内在浏览器上进行多少次比较?这是一个很难回答的问题,因为有许多因素在起作用,但这是一个测试用例:http : //jsperf.com/angularjs-digest/6,它创建了10,000个观察者。在现代浏览器上,这仅需不到6毫秒。在Internet Explorer 8上,大约需要40毫秒。如你所见,即使这些天在缓慢的浏览器上,这也不是问题。需要注意的是:比较必须很简单才能适应时间限制…不幸的是,将慢速比较添加到AngularJS中太容易了,因此当你不知道自己要做什么时,很容易构建慢速应用程序是做。但是我们希望通过提供一个检测模块来解决这个问题,该模块将向你展示哪些是比较慢的比较。

事实证明,视频游戏和GPU使用脏检查方法,特别是因为它是一致的。只要它们超过了监视器的刷新率(通常为50-60 Hz,或每16.6-20 ms),任何超过该频率的性能都是浪费,因此,与提高FPS相比,最好消耗更多的资源。

2020-04-23