AngularJS框架中,数据绑定是如何工作的?

我还没有找到their site的技术细节.当数据从视图传播到模型时,它的工作原理或多或少是清楚的.但是AngularJS如何在没有setter和getter的情况下跟踪模型属性的变化呢?

I found that there are JavaScript watchers that may do this work. But they are not supported in Internet Explorer 6 and Internet Explorer 7. So how does AngularJS know that I changed for example the following and reflected this change on a view?

myobject.myproperty="new value";

推荐答案

AngularJS记住该值并将其与之前的值进行比较.这是基本的肮脏判断.如果值发生更改,则它会激发Change事件.

$apply()方法是您从非AngularJS世界转换到AngularJS世界时调用的方法,它称为$digest().摘要只是一种普通的、老式的肮脏判断.它可以在所有浏览器上运行,并且完全可以预测.

对比脏判断(AngularJS)和更改侦听器(KnockoutJSBackbone.js):虽然脏判断看起来很简单,甚至效率低下(我将在后面讨论),但事实证明它在语义上一直是正确的,而change Listener有很多奇怪的角落 case ,需要依赖项跟踪之类的东西来让它在语义上更加正确.KnockoutJS依赖项跟踪是解决AngularJS没有的问题的一个聪明功能.

Issues with change listeners:

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

What about performance?

因此,我们似乎很慢,因为肮脏的判断效率很低.这就是我们需要研究实数的地方,而不仅仅是理论上的论证,但首先让我们定义一些约束条件.

人类是:

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

  • Limited-你不能在一个页面上向一个人显示超过2000条信息.除此之外,任何东西都是非常糟糕的UI,人类无论如何都无法处理它.

So the real question is this: How many comparisons can you do on a browser in 50 ms? This is a hard question to answer as many factors come into play, but here is a test case: http://jsperf.com/angularjs-digest/6 which creates 10,000 watchers. On a modern browser this takes just under 6 ms. On Internet Explorer 8 it takes about 40 ms. As you can see, this is not an issue even on slow browsers these days. There is a caveat: The comparisons need to be simple to fit into the time limit... Unfortunately it is way too easy to add a slow comparison into AngularJS, so it is easy to build slow applications when you don't know what you are doing. But we hope to have an answer by providing an instrumentation module, which would show you which are the slow comparisons.

事实证明,视频游戏和GPU使用脏判断方法,特别是因为它是一致的.只要它们超过了监视器刷新率(通常为50-60赫兹,或每16.6-20毫秒一次),超过这一速度的任何性能都是浪费,因此你最好画更多的东西,而不是获得更高的FPS.

Javascript相关问答推荐

ChartJS:分组堆叠条形图渲染错误

Angular 拦截器错误处理删除方法问题

ReactJS中的material UI自动完成类别

如何使用Echart 5.5.0创建箱形图

我试图实现用户验证的reduxstore 和操作中出了什么问题?

防止用户在selectizeInput中取消 Select 选项

如何粗体匹配的字母时输入搜索框使用javascript?

为什么当我解析一个promise时,输出处于挂起状态?

如何让npx在windows中运行js脚本?

如何通过使用vanilla JS限制字体大小增加或减少两次来改变字体大小

我可以使用使用node.js创建的本地主机来存储我网站上提交的所有数据吗?没有SQL或任何数据库.只有HTML语言

如何在使用rhandsontable生成表时扩展数字输入验证?

当输入字段无效时,我的应用程序不会返回错误

在使用位板时,如何在Java脚本中判断Connect 4板中中柱的对称性?

映射类型定义,其中值对应于键

使用getBorbingClientRect()更改绝对元素位置

为什么我的自定义元素没有被垃圾回收?

SPAN不会在点击时关闭模式,尽管它们可以发送日志(log)等

将对象推送到数组会导致复制

无法检索与Puppeteer的蒸汽游戏的Bundle 包价格