数据绑定在AngularJS中如何工作? [英] How does data binding work in AngularJS?

查看:132
本文介绍了数据绑定在AngularJS中如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我没有找到有关<一个href =http://angularjs.org =noreferrer>他们的网站。当数据从视图传播到模型时,它或多或少清楚它的工作原理。但是,AngularJS如何跟踪没有setter和getter的模型属性的变化?



我发现有一个 JavaScript观察者,可以做这个工作。但是, Internet Explorer 6  6 Internet  Explorer  7 。那么AngularJS如何知道我改变了以下的例子,并在一个视图中反映了这个变化?

  myobject.myproperty =new值; 


解决方案

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



$ apply()当您从非AngularJS世界转换为AngularJS世界时,您所呼吁的是调用 $ digest()。一个消息只是简单的脏的检查。它适用于所有浏览器,并且是完全可预测的。



对比脏检查(AngularJS)与更改监听器( KnockoutJS Backbone.js ):虽然脏的检查似乎简单,甚至低效(稍后我会解决),事实证明它在所有的时间都是语义上正确的,而改变听众有很多奇怪的角落,需要像依赖关系跟踪这样的东西,使它更语义上正确。 KnockoutJS依赖关系跟踪是AngularJS没有的问题的一个很好的功能。



更改听众的问题:




  • 语法是残酷的,因为浏览器本身不支持。是的,有代理,但它们在所有情况下都不是语义上正确的,当然在旧的浏览器上也没有代理。最重要的是,肮脏检查允许您执行 POJO ,而KnockoutJS和Backbone.js会强制您继承自己的课程,并通过访问者访问您的数据。

  • 更改合并。假设你有一个项目的数组。假设您要将项目添加到数组中,因为您正在循环添加,每次添加时,都是在更改时触发事件,即渲染UI。这对性能来说是非常糟糕的。你想要的是更新UI只有一次,最后。更改事件太细了。

  • 更改侦听器会立即触发setter,这是一个问题,因为更改侦听器可以进一步更改数据,从而触发更多更改事件。这是坏的,因为在你的堆栈你可能有几个改变事件发生一次。假设你有两个数组需要保持同步,无论什么原因。你只能添加到一个或另一个,但每次你添加一个消防改变事件,现在有一个不一致的世界观。这是一个非常类似的问题,线程锁定,JavaScript避免了每个回调执行完成和完成。变更事件突破了这一点,因为设置者可能会产生深远的后果,这是不希望和不明显的,这再次导致了线程问题。事实证明,你想要做的是延迟监听器执行,并保证每次只运行一个监听器,因此任何代码都可以自由地更改数据,并且知道在执行此操作时没有其他代码运行



性能如何?



所以看来,慢,因为脏检查效率低下。这是我们需要看实际数字而不仅仅是理论论据的地方,但首先我们来定义一些限制。



人类是:




  • - 超过50 ms的任何东西都是人类不可察觉的,因此可以被视为即时。


  • - 您不能在一个页面上向人们显示超过约2000条信息。任何比这更糟糕的UI是非常糟糕的UI,人类无法处理这个。




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



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

How does data binding work in the AngularJS framework?

I haven't found technical details on their site. It's more or less clear how it works when data is propagated from view to model. But how does AngularJS track changes of model properties without setters and getters?

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 remembers the value and compares it to a previous value. This is basic dirty-checking. If there is a change in value, then it fires the change event.

The $apply() method, which is what you call when you are transitioning from a non-AngularJS world into an AngularJS world, calls $digest(). A digest is just plain old dirty-checking. It works on all browsers and is totally predictable.

To contrast dirty-checking (AngularJS) vs change listeners (KnockoutJS and Backbone.js): While dirty-checking may seem simple, and even inefficient (I will address that later), it turns out that it is semantically correct all the time, while change listeners have lots of weird corner cases and need things like dependency tracking to make it more semantically correct. KnockoutJS dependency tracking is a clever feature for a problem which AngularJS does not have.

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?

So it may seem that we are slow, since dirty-checking is inefficient. This is where we need to look at real numbers rather than just have theoretical arguments, but first let's define some constraints.

Humans are:

  • 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.

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.

It turns out that video games and GPUs use the dirty-checking approach, specifically because it is consistent. As long as they get over the monitor refresh rate (typically 50-60 Hz, or every 16.6-20 ms), any performance over that is a waste, so you're better off drawing more stuff, than getting FPS higher.

这篇关于数据绑定在AngularJS中如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆