angularjs笔记
  • Introduction
  • 依赖注入
  • 作用域
  • 数据绑定
    • 控制器->模板->控制器->模板
  • 多个控制器
  • $scope对象
    • $apply方法、$digest方法
    • $watch方法
    • 示例:购物车
  • 模块和控制器
  • $provide对象的provider、factory、service方法
    • 多个控制器内共享数据
  • 过滤器(Filters)
    • number、currency、date
    • limitTo、lowercase、uppercase
    • filter、orderBy、json
    • 示例:产品列表
    • 自定义过滤器
  • 控制器(controller)
    • 显式和隐式依赖注入
  • 指令
    • Angular 内置指令
    • Angular 自定义指令
      • restrict、template、replace属性
      • templateUrl属性
      • transclude、priority、terminal属性
      • compile && link属性
      • controller && controllAs属性
      • require属性
      • scope属性
  • Module里其他方法
    • constant、value、run方法
  • Form表单
    • 示例:注册页
  • XHR和服务器端的通信
    • $http
  • JavaScript基础
    • .isFunction是否为函数
  • 资料链接
  • 功能组件
    • Tooltip
    • CSV
  • 其他
    • $watchCollection
    • $controller 继承
    • 两个对象合并
    • 页面关闭
    • AngularJs 时间格式化处理
    • 数据的本地存储
    • 页面的URL
Powered by GitBook
On this page
  • $apply
  • angular是怎么知道变量发生了改变
  • $digest
  • 简单理解过程

Was this helpful?

  1. $scope对象

$apply方法、$digest方法

$apply

  • $scope.$apply(expression)

  • $apply()方法可以在angular框架之外执行angular JS的表达式,例如:DOM事件、setTimeout、XHR或其他第三方的库。

angular是怎么知道变量发生了改变

要知道一个变量变了,方法不外乎两种

  1. 能通过固定的接口才能改变变量的值,比如说只能通过 set() 设置变量的值,set被调用时比较一下就知道了。

    这中方法的缺点洗是写法繁琐

  2. 脏检查,将原对象复制一份快照,在某个时间,比较现在对象与快照的值,如果不一样就表明发生变化,这个策略要保留两份变量,而且要遍历对象,比较每个属性,这样会有一定性能问题

angular的策略:angular的实现是使用脏检查

  1. 不会脏检查所有的对象,当对象被绑定到html中,这个对象添加为检查对象(watcher)。

  2. 不会脏检查所有的属性,同样当属性被绑定后,这个属性会被列为检查的属性。

在angular程序初始化时,会将绑定的对象的属性添加为监听对象(watcher),也就是说一个对象绑定了N个属性,就会添加N个watcher。

什么时候去脏检查

angular 所系统的方法中都会触发比较事件,比如:controller 初始化的时候,所有以ng-开头的事件执行后,都会触发脏检查。

手动触发脏检查

  • $apply仅仅只是进⼊入angular context ,然后通过$digest去触发脏检查

  • $apply如果不给参数的话,会检查该$scope⾥里的所有监听的属性,推荐给上参数

例子

index.html

<div ng-app="myApp">

        <div ng-controller="firstController">
            {{date}}
        </div>
    </div>
    <script src="//cdn.bootcss.com/angular.js/1.4.8/angular.js"></script>
    <script type="text/javascript" src="app/index.js"></script>

app/index.js

app.controller('firstController', function($scope){

    $scope.date = new Date();

//    setInterval(function(){
//        // 这里虽然变 但是并没有触发 脏检查
//        $scope.date = new Date();
//
//    },1000)

    setInterval(function(){
        $scope.$apply(function(){
            $scope.date = new Date();
            //....会去触发脏检查
        })
    },1000)


    // 触发一次脏检查
});

注意如下代码,虽然打印出来每秒将会触发时间,但是没有触发脏检查,不会触发页面上的改变。

setInterval(function(){
    // 这里虽然变 但是并没有触发 脏检查
    $scope.date = new Date();
    console.log(new Date());

},1000)

$digest

  • 所属的scope和其所有子scope的脏检查,脏检查又会触发$watch(),整个Angular双向绑定机制就活了起来~

  • 不建议直接调用$digest(),而应该使用$apply(),$apply其实不能把信直接送给$digest,之间还有$eval门卫把关,如果$apply带的表达式不合法,$eval会把错误送交$exceptionHandler,合法才触发digest,所以更安全。

简单理解过程

触发$apply,执行完,执行脏检查,检查每个$scope下的属性是否有变化,有变化的话,触发watch监听事件,页面上的对应值value和绑定的model值都会跟着改变。

并不是所有的时间都需要$apply.当自定义的地方才需要。

Previous$scope对象Next$watch方法

Last updated 5 years ago

Was this helpful?