AngularJS如何实现其双向数据绑定机制?

AngularJS如何实现其双向数据绑定机制?,angularjs,2-way-object-databinding,Angularjs,2 Way Object Databinding,AngularJS允许您实现双向数据绑定。然而,有趣的是它是如何检测模型变化的?模型通常是一个简单的对象,如下面的代码。我们可以更改$scope.user的name属性,但是AngularJS如何检测模型的更改?AngularJS是否枚举$scope对象的所有属性 angular.module('myApp', []) .controller('BusinessCardController', function($scope){ $scope.user = {

AngularJS允许您实现双向数据绑定。然而,有趣的是它是如何检测模型变化的?模型通常是一个简单的对象,如下面的代码。我们可以更改
$scope.user
的name属性,但是AngularJS如何检测模型的更改?AngularJS是否枚举
$scope
对象的所有属性

angular.module('myApp', [])
      .controller('BusinessCardController', function($scope){
        $scope.user = {
          name: 'Tanay Pant'
        }
      });

<input type="text" ng-model="user.name" placeholder="Full Name" />
angular.module('myApp',[])
.controller('BusinessCardController',函数($scope){
$scope.user={
名称:'Tanay Pant'
}
});

有一个摘要循环,范围检查所有$watch表达式,并将它们与前面的值进行比较。它查看对象模型的变化,如果旧值与新值不同,AngularJS将更新相应的位置,即脏检查

为了执行摘要循环,必须运行$apply(fn),这就是从JavaScript进入角度世界的方式。
$apply(fn)
如何被调用(取自AngularJs):

  • 浏览器的事件循环等待事件到达。事件是用户交互、计时器事件或网络事件(来自服务器的响应)
  • 执行事件的回调。这将进入JavaScript上下文。回调可以修改DOM结构
  • 执行回调后,浏览器将离开JavaScript上下文,并根据DOM更改重新呈现视图
  • 为了实现双向绑定,指令注册观察者。为了使页面快速高效,我们需要尝试减少我们创建的所有观察者。因此,在使用双向绑定时应该小心,即仅在真正需要时使用。否则,请使用单向:

    {{::vm.title}

    在这里,很明显,当用户在页面上时,页面的标题可能不会更改,或者如果更改了,则需要查看新的标题。因此,我们可以使用
    在模板链接阶段注册单向绑定


    我看到的观察者爆炸的主要问题是数百行的网格。如果这些行有相当多的列,并且每个单元格中都有双向数据绑定,那么您就可以享受了。您可以像在调制解调器时代一样坐下来等待页面加载

    双向绑定几乎只限于使用
    ng model
    的元素。从视图到模型的方向使用标准事件处理程序来检测必须在模型内更新的更改(例如,
    onchange
    )。从模型返回视图的方向在
    $digest
    期间更新。但我们不直接调用
    $digest

    页面上每个要响应摘要循环的元素都会在某个地方使用
    $watch
    将侦听器和表达式附加到其作用域。当您编写
    {{foo()}}
    或使用
    ng model='user.name'
    时,内部会代表您使用Javascript表达式调用
    $watch
    ,该表达式将在每次运行摘要循环时运行。这种注册可能发生在模板的编译过程中(我们的第一个示例),也可能发生在指令的链接阶段(我们的第二个示例)

    这里没有魔法。附加的侦听器是常规函数——在我们的示例中,为您提供了表达式
    foo()
    的侦听器,它将更新页面上的html文本,而表达式
    user.name
    的侦听器将调用
    setText
    ,或
    setOption
    ,或附加了
    ng型号
    的特定输入所需的任何内容

    虽然angular可以处理大部分侦听,但您可以在任何可以访问作用域的函数中手动将自己的监视表达式与自己的侦听器连接起来(作用域很重要,因为如果删除页面的相应部分,我们将删除这些监视器)。注意过度。绑定不是免费的,绑定的内容越多,页面响应的速度就越慢。一次性绑定是降低此成本的一种方法。将
    $on
    $emit
    $broadcast
    一起使用是另一种方法


    那么什么时候叫文摘?这当然不是自动的。如果摘要循环正在运行,则意味着在其作用域或根作用域中有一个名为
    $apply
    的人
    ng model
    附加处理程序,这些处理程序将响应常规html事件,并代表您调用
    $apply
    。但另一方面,
    foo()。幸运的是,您为angular填写的大多数函数都会通过调用
    $apply
    来包装这些函数,因此您不必经常自己进行调用(例如,
    $timeout
    $apply
    包装,这就是为什么我们使用它而不是
    setTimeout
    )。但是,如果您使用的是angular(连接到事件的第三方库)范围之外的内容,您需要记住自己调用
    $apply
    ,就像上面一样,您可以在任何可以访问范围的地方手动调用
    $apply

    以实现数据绑定,AngularJS使用$watch API来观察作用域上的更改。AngularJS为作用域上的每个变量注册了观察者,以观察其中的值。如果作用域上变量的值发生更改,则视图将自动更新

    这是因为触发了$digest循环。因此,AngularJS处理当前作用域上所有注册的观察者和子对象,检查更新并调用专用的观察者侦听器,直到模型稳定并且不再触发侦听器。一旦