zoukankan      html  css  js  c++  java
  • AangularJS入门总结三

    (参考的资料)

    1. 数据绑定的原理:

       (1)  $watch 队列: 在DOM中每次绑定一些东西,就会往$watch队列中插入一条$watch;

                每一个绑定到了DOM上的数据都会生成一个$watch;我们的模版加载完毕时,在linking阶段(Angular分为compile阶段和linking阶段),

                Angular解释器会寻找每个directive,然后生成每个需要的$watch。

       (2)  $digest 循环:当浏览器接收到可以被angular context处理的事件时,$digest循环就会触发;

                这个循环是由两个更小的循环组合起来的。一个处理evalAsync队列,另一个处理$watch队列。 

                处理$watch队列:循环$watch 队列,发现这个队列中的值有变化,就执行回调函数,执行相应的DOM操作;  

                        如果有至少一个更新过,这个循环就会再次触发,直到所有的$watch都没有变化。这样就能够保证每个model都已经不会再变化。

                        如果循环超过10次的话,它将会抛出一个异常,防止无限循环。当$digest循环结束时,DOM相应地变化;  

                        (ng-click不生成$watch(函数是不会变的));  

       (3)  $apply        :  $apply决定什么事件进入 angular上下文环境;、

                 当事件触发时,你调用$apply,它会进入angular context,如果没有调用就不会进入。

                 当你点击带有ng-click的元素时,就会被封装到一个$apply调用。如果你有一个ng-model="foo"的输入框,然后你敲一个f,

                 事件就会这样调用$apply("foo = 'f';")。

                 Angular什么时候不会自动为我们调用$apply呢?Angular不会更新我绑定的东西的解决方法scope.$apply(function() {});

                 $apply是我们的$scope(或者是direcvie里的link函数中的scope)的一个函数,调用它会强制一次$digest循环

                 (除非当前正在执行循环,这种情况下会抛出一个异常)。

    2. 自定义指令:angular通过指令的方式实现了HTML的扩展

           指令在框架中的执行流程:

              --浏览器得到 HTML 字符串内容,解析得到 DOM 结构。

              --Angular引入,把 DOM 结构扔给 $compile 函数处理:

                 ---找出 DOM 结构中有变量的占位符;

                 ---匹配找出 DOM 中包含的所有指令引用

                 ---把指令关联到 DOM;

                 ---关联到 DOM 的多个指令按权重排列;

                 ---执行指令中的 compile 函数(改变 DOM 结构,返回 link 函数);

                 ---得到的所有 link 函数组成一个列表作为 $compile 函数的返回。

              --执行 link 函数(连接模板的 scope)。

                 ---注意区别一下$compile和compile,前者是Angular内部的编译服务,后者是指令中的编译函数,两者发挥作用的范围不同。

                   compile 和 link 函数息息相关又有所区别;

                  Angular编译的工作是解析指令、绑定监听器、替换模板中的变量等。工作方式很像高级语言编辑中的递归、堆栈过程,所以起名为编译;

            指令的使用方式及命名方法:

                指令的几种使用方式如下:(常用的就是作为  标签  和  属性)

                  作为标签:<my-dir></my-dir>

                  作为属性:<span my-dir="exp"></span>

                  作为注释:<!-- directive: my-dir exp -->

                  作为类名:<span class="my-dir: exp;"></span>

                  指令命名时用驼峰规则,使用时用-分割各单词。如:定义myDirective,使用时像这样:<my-directive>;

            自定义指令的配置参数:

                  下面是定义一个标准指令的示例,可配置的参数包括以下部分:

                    myModule.directive('namespaceDirectiveName', function factory(injectables) {

                            var directiveDefinitionObject = {

                                  restrict: string,           //指令的使用方式,包括标签,属性,类,注释

                                  priority: number,        //指令执行的优先级

                                  template: string,        //指令使用的模板,用HTML字符串的形式表示

                                  templateUrl: string,       //从指定的url地址加载模板

                                  replace: bool,           //是否用模板替换当前元素,若为false,则append在当前元素上

                                  transclude: bool,        //是否将当前元素的内容转移到模板中

                                  scope: bool or object,     //指定指令的作用域

                                controller: function controllerConstructor($scope, $element, $attrs, $transclude){...},  //定义与其他指令进行交互的接口函数

                                  require: string,      //指定需要依赖的其他指令

                           link: function postLink(scope, iElement, iAttrs) {...},                //以编程的方式操作DOM,包括添加监听器等

                                  compile: function compile(tElement, tAttrs, transclude){

                                            return: {

                                                      pre: function preLink(scope, iElement, iAttrs, controller){...},

                                                      post: function postLink(scope, iElement, iAttrs, controller){...}

                                                }

                                      }                                  //编程的方式修改DOM模板的副本,可以返回链接函数;

                            };

                            return directiveDefinitionObject;

                     });

                    (根据自己的需要来选择使用哪些参数。priority和compile用的比较少,template和templateUrl又是互斥的,两者选其一即可

                        指令的表现配置参数:restrict、template、templateUrl、replace、transclude;

                        指令的行为配置参数:compile  和  link;

                        指令划分作用域配置参数:scope;

                        指令间通信配置参数:controller和require。

                指令的表现参数restrict、template、templateUrl、replace、transclude

                  transclude:指定了transclude为true,并在模板标签上面使用了ng-transclude指令,用来告诉指令把内容转移到的位置;

                  restirct用来指定指令的使用类型,其取值及含义:

    取值

    含义

    使用示例

    E

    标签

    <my-menu title=Products></my-menu>

    A

    属性

    <div my-menu=Products></div>

    C

    <div class="my-menu":Products></div>

    M

    注释

    <!--directive:my-menu Products-->

                 指令的行为参数:compile  和  link:

                    如果指令只进行DOM的修改,不进行数据绑定,那么配置在compile函数中,如果指令要进行数据绑定,那么配置在link函数中。

                    compile拿到的是编译前的,是从template里拿过来的,link拿到的是编译后的,已经与作用域建立了关联,这也正是link中可以进行数据绑定的原因。

                 指令的划分作用域参数:scope:

                    作用是描述指令与父作用域的关系;

                    指令与父作用域(就是控制器所管辖的范围)的关系可以有如下取值:

    取值

    说明

    false

    默认值。使用父作用域作为自己的作用域

    true

    新建一个作用域,该作用域继承父作用域

    javascript对象

    与父作用域隔离,并指定可以从父作用域访问的变量

                    绑定策略,它的取值按照如下的规则:

    符号

    说明

    举例

          @

    传递一个字符串作为属性的值

    str : ‘@string’

          =

    使用父作用域中的一个属性,绑定数据到指令的属性中

    name : ‘=username’

          &

    使用父作用域中的一个函数,可以在指令中调用

    getName : ‘&getUserName’

                       自定义指令中的 scope;    用符号前缀来说明如何为指令传值;

                       scope : {
                                         name : ‘=username’
                                    },

                指令间通信参数:controller 和 require:

                      当想做的组件稍微复杂一点,就不是一个指令可以搞定的了,就需要指令与指令的协作才可以完成,这就需要进行指令间通信;

                      controller  数用于定义指令对外提供的接口,它的写法如下:

                            controller: function controllerConstructor($scope, $element, $attrs, $transclude){}

                      require:它的值是一个字符串,就是所依赖的指令的名字,这样框架就能按照你指定的名字来从对应的指令上面寻找定义好的controller了。

                           不过还稍稍有点特别的地方,为了让框架寻找的时候更轻松些,我们可以在名字前面加个小小的前缀:^,表示从父节点上寻找,

                           使用起来像这样:require : ‘^directiveName’,如果不加,$compile服务只会从节点本身寻找。

                           另外还可以使用前缀:?,此前缀将告诉$compile服务,如果所需的controller没找到,不要抛出异常。

        3. 性能:

              缺点:当处理包含复杂数据结构的大型列表时,其运行速度就会非常慢;

          两个主要性能问题:一个与“ng-repeat ”指令有关,另一个与过滤器有关;

          最好的办法是限制所显示列表的大小。可通过分页、添加无限滚动条来实现;

          分页,我们可以使用AngularJS的“limitTo”过滤器(AngularJS1.1.4版本以后)和“startFrom”过滤器。可以通过限制显示列表的大小来减少渲染时间。这是减少渲染时间最高效的方法。

  • 相关阅读:
    React爬坑秘籍(一)——提升渲染性能
    (转)Chrome开发者工具不完全指南(一、基础功能篇)
    React-Todos
    webpack前端模块加载工具
    Python面试笔记二
    Python面试笔记一
    Python面试笔记四
    Python面试笔记三
    Mysql性能优化一
    公共的JS组件-告别CURD
  • 原文地址:https://www.cnblogs.com/liaolei1/p/6852962.html
Copyright © 2011-2022 走看看