zoukankan      html  css  js  c++  java
  • 迈向angularjs2系列(4):脏值检测机制

    目录

    一: 概念简介

     脏值检测,简单的说就是在MVC的构架中,视图会通过模型的change事件来更新自己。

    脏值检测的核心代码是观察者模式的实现,其机制会执行digest循环,在特定UI组件的上下文执行注册的各种表达式。

    那么脏值检测在单页应用扮演了什么角色呢?

     

    为了支持单页SPA应用,angular1引入了指令的概念,能够扩展HTML标签并且封装相关的DOM逻辑,以此来构建组件,组件再组合成一个个网页。angular2也保留了指令的概念。那么angular2和1版本的区别在哪里呢?angular2的指令则是简化版的指令API,能通过属性型的指令给DOM标签添加行为。

    而与此同时,组件则可以看做指令API的补充,既可以添加模板,也可以添加行为,组件继承自指令。

    @Directive({
      selector: '[saTooltip]'
    })
    export class Tooltip {
     //
    }

    二: angular1中的脏值检测

    ch4-change-detection/angular1-demo/index.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="angular.js"></script>
        <!--引入版本为1.5.0-->
        <script>
            angular.module("app",[])
                .controller("mainCtrl",function($scope){
                $scope.label="hello world!";
            });
        </script>
    </head>
    <body ng-app="app" ng-controller="mainCtrl">
    
         <div>
             <span>label值:{{label}}</span>
             <br/>
             <input type="text" ng-model="label"/>
         </div>
    </body>
    </html>

    浏览器结果

    angular1的数据绑定,酷炫而神秘!可是它幕后实际发生了什么呢?

    (1)首先,在指令ng-model和双大括号(实际上是ng-bind指令)内部绑定了多个watcher(监视器)。

    (2)接下来,当指定的事件发生之后,angular循环遍历所有的监视器,并执行对应scope上下文的表达式。这里就是digest循环。

    (3)最后,比对两次结果,如果不相同就调用回调函数。

    但这种发生特定事件(有可能在框架管理范围内,也可能在范围外部)会调用digest循环有缺点。比如回调函数有setTimeOut定时器,定时器把绑定到Scope上的属性给修改了,那么angular就无法察觉对象的改变了。angular2解决这个问题。

    二: angular2更优的脏值检测

    1.zone.js库

    zone.js是angular2的一个库,可以在javascript实现各种分区。分区代表一个执行上下文。angular2利用了zone.js来拦截浏览器中的各种异步事件,然后在正确的时机调用digest循环,完全消除了需要angular开发者显式调用digest循环的情况。

    2.单向数据流

    在第一章的例子里,label表达式在ng-model指令下发生改变,也会通知label的双大括号表达式改变值,这隐含了指令之间互相影响、有依赖关系。跨监视器的依赖会创建出各种纠缠不清的额数据流,导致最后可能很难追踪,进而导致难以预料的错误。

    angular2保留了脏值检测的概念用来检测数据,但强制使用了单向数据流。

    实现的方式:

    禁止不同的监视器互相依赖,digest循环只要运行一次就好了。

    单向数据流好处不仅仅于此,更简单的数据流,而且性能提高了

    3.增强angular1的脏值检测

    我们说到digest循环有比较的步骤,比较操作的最佳算法是根据表达式返回值的类型进行比较。angular1有的是浅比较,有的是深比较,而且开发者并不能自己预先决定使用哪种比较。angular2团队把比较功能分离到了differ(差异比较器)中,那么开发者就可以通过2个基础类扩展自定义算法了,从而有了对脏值检测机制的完全控制。

    ●KeyValueDiffer。键值对型差异比较器。

    ●IterableDiffer。迭代型差异比较器。

  • 相关阅读:
    ElasticSearch——分页查询
    Canal——写入到ES中数据错乱
    HBase管理与监控——WebUI
    '$.browser.msie' 为空或不是对象
    input file 获取不到Request.Files 解决办法
    .NET读取服务器或本地文件
    .NET将服务器文件导出
    .Net 中HashTable,HashMap 和 Dictionary<key,value> 和List<T>和DataTable的比较
    JavaScript跨域调用基于JSON的RESTful API
    WCF项目问题2-无法激活服务,因为它需要 ASP.NET 兼容性。没有未此应用程序启用 ASP.NET 兼容性。请在 web.config 中启用 ASP.NET 兼容性,或将 AspNetCompatibilityRequirementsAttribute.AspNetCompatibilityRequirementsMode 属性设置为 Required 以外的值。
  • 原文地址:https://www.cnblogs.com/chenmeng2062/p/7105745.html
Copyright © 2011-2022 走看看