zoukankan      html  css  js  c++  java
  • angularjs的directive的属性含义详解

     在介绍directive之前,我想先讲讲MVC这个框架的相关知识。这样可以更好的理解angular。

    什么是MVC?mvc是一种设计模式,它把应用划分为三个部分,数据(模型),展现层(视图),控制交互层(控制器),一个时间的发生时这样的过程:

    1.用户和应用产生交互

    2.控制器的事件处理器被触发

    3.控制器从模型中请求数据,并将其交给视图

    4.视图将数据呈现给用户。

    模型

    模型用来存放应用的所有数据对象,模型不必知晓视图和控制器的细节,模型只需包含数据及直接和这些数据相关的逻辑。任何事件处理代码、视图模板,以及那些和模型无关的逻辑都应当隔离在模型之外。将模型和视图的代码混在一起,是违反MVC架构原则的。模型是最应该从你的应用中解耦出来的部分。

    当控制器从服务端抓取数据或者创建新的记录时,它就将数据包装成模型实例,也就是说,我们的数据是面向对象的,任何定义在这个数据模型上的函数或者逻辑都可以直接被调用。

    因此,不要这样做:  

    var user = users["foo"];
    destroyUser(user);
    

      上面的代码没有命名空间的概念,并且不是面向对象的。如果在应用中定义了另一个destoryUser()函数的话,两个函数就会产生冲突。我们应当确保全局变量和函数的个数尽可能少.而要这样做。

    var user = User.find("foo");
    user.destroy();
    

      上面的代码中,destory()函数是存放在命名空间User的实例中的。这种代码更加清晰,而且非常容易做继承,类似destory()的这种函数就不用在每个模型中都定义一遍了。

    视图

    视图层是呈现给用户的,用户与之产生交互,在JavaScript 应用中,视图大都是由HTML、CSS和JavaScript模板组成的。除了模板中简单的条件语句之外,视图不应当包含任何其他逻辑。

    这并不是说MVC不允许包含视觉呈现相关的逻辑,只要这部分逻辑没有定义在视图之内即可。我们将视觉呈现逻辑归类为“视图助手”(helper):和视图有关的独立的小型工具函数。

    反例——formatDate()函数直接插入视图:

    // template.html
    <div>
        <script>
            function formatDate(date) {
                /* ... */
            };
        </script>
    
        ${ formatDate(this.date) }
    </div>
    

      应该这样做——所有视觉呈现逻辑都包含在helper变量中,这是一个命名空间,可以防止冲突并保持代码清晰、可扩展:

      

    // helper.js
    var helper = {};
    helper.formatDate = function(){ /* ... */ };
    
    // template.html
    <div>
        ${ helper.formatDate(this.date) }
    </div>
    

      控制器

    控制器是模型和视图之间的纽带,控制器从视图获得时间和输入,对它们惊醒处理(很可能包含模型),并相应的跟新视图。当页面加载工作时,控制器会给视图添加事件监听,比如监听表单提交或者按钮点击。然后,当用户和应用产生交互时,控制器中的事件触发器就开始工作了。

    下面用jQuery实现一个例子:

    var Controller = {};
    
    // 使用匿名函数来封装一个作用域
    (Controller.users = function($){
    
        var nameClick = function(){
            /* ... */
        };
    
        // 在页面加载时绑定事件监听
        $(function(){
            $("#view .name").click(nameClick);
        });
    })(jQuery);
    

      上面的代码创建了users控制器,这个控制器是放在Controller变量下的命名空间。然后用了一个匿名函数封装了一个作用域,以避免对全局作用域造成污染。当页面加载时,程序给视图元素绑定了点击事件的监听。

    上面就是mvc的简单介绍。下面继续directive的属性讲解。

    基本上每个directive都会经过$compile编译,然后通过link函数来拓展相应的DOM元素。下面介绍常用的directive定义的对象:

    priority

    当有多个directive定义在同一个DOM元素上时,有必要指定directive的应用顺序。priority对象通常用数字表示,数字越大的,相应的指定便优先编译,相反该directive对应的link函数便越靠后执行。priority的值默认为是0.

     scope(讲到这个,值得提一提$scope对象,还有在controller中使用$scope和this(当在html中使用controller as时可以使用)的区别,感兴趣的话自行搜索)

    它的值有三种;true,false(默认),object(对象)。

    什么是angular中的scope?

    scope(http://code.angularjs.org/1.0.2/docs/api/ng.$rootScope.Scope)是一个指向model的object。也是表达式的的执行上下文(请自行了解执行上下文的概念)。angular中提供了一些常用API:$watch API(http://code.angularjs.org/1.0.2/docs/api/ng.$rootScope.Scope#$watch),用于监测model的变化,$apply API(http://code.angularjs.org/1.0.2/docs/api/ng.$rootScope.Scope#$apply),用于监测angular 定义的对象内外的所有model的变化。

    在angular中,子作用域一般是通过原型继承机制继承其父作用域的属性和方法,但是有一个例外:在directive中,使用scope:{...},这种方式创建的作用域是一个独立的(isolate)作用域,它也有父作用域,但父作用域不在其原型链上,不会对父作用域原型继承,这种方式定义作用域通常用于构造可复用的directive组件,因为这样定义的scope,不会直接访问或者时候修改父作用域的属性,不会产生意外的副作用。

    如果我们在子作用域中访问一个父作用域中定义的属性,那么程序会首先在子作用域中寻找该属性,没找到在从原型链上的父作用域中寻找,在没找到,再往上一级原型链找。在angular中,作用域原型链的顶端是$rootScope。

    在单独的directive中,scope的概念还是比较清晰的。

    当scope取值为false时,此时directive没有独立的scope对象,link函数中引用的scope对象为来自于当前节点的默认controller。

    当scope取值为true是时,directive拥有独立的scope对象,此scope是由父scope继承而来,可以访问父scope中的所有属性,此时通过javasript原型继承。值得注意的是:当给此scope继承而来的属性名称赋值时,子scope会相应建立一个本地属性,此时改变的是本scope的变量属性,父scope中的属性是不会改变的。

    当scope取值为{propertyName:"=@propertyValue},此时directive拥有一个隔离的scope对象,其实就是一个全新的scope对象,和上面取值的区别就是不能通过原型继承访问父scope中的属性,但是可以通过$parent属性去访问父scope中对象属性的。

    下面讲讲当scope取值为{...}时,申明scope对象的引用修饰符的用法:(http://stackoverflow.com/questions/14050195/angularjs-what-is-the-difference-between-and-in-directive-scope)

    1.=或者=attr  隔离作用域的属性与父作用域的属性进行双向绑定,任何一方修改都会影响对方,此时指令中的属性取值为controller中对应的$scope上属性的值,这是最常用的方式;

    2.@或者@attr  此时指令中的属性取值为html中的字面量或者直接量。这样是建立一个local scope property到DOM的property的绑定,因为值总是string类型,故这个值总是返回一个字符串,并且字符串的值永远是从父作用域继承而来的(即只能读取父作用域中属性值,不能修改,属于单向绑定)。如果没有通过@attr指定属性名称,那么本地名称将于DOM的属性一致。例如<widget my-attr=”hello {{name}}”>,widget的scope定义为:{localName:’@myAttr’}。那么,widget scope property的localName会映射出”hello {{name}}"转换后的真实值。name属性值改变后,widget scope的localName属性也会相应地改变(仅仅单向,与上面的”=”不同)。name属性是在父scope读取的(不是组件scope).

     3. & or &attr “Isolate”作用域把父作用域的属性包装成一个函数,从而以函数的方式读写父作用域的属性,包装方法是$parse();

     controller

    这是嵌套directive之间交互的重要属性对象。

     套用一个经典定义( what the O'Reily AngularJS book by the Google Team has to say):Controller - Create a controller which publishes an API for communicating across directives. A good example is Directive to Directive Communication。意即这个controller是用来存放一些可以在各个directive之间的共享的方法。当两个或更多的directive之间需要通信时(即directive A需要用到directive B中的方法M),这时方法M就可以在directive B中的controller对象中来定义这个方法。此时方法M便类似一些公共的API(可以供其他的directive使用。)详情请参考:http://www.cnblogs.com/xing901022/p/4290411.html

     这个controller可以注入以下本地变量:

    $scope (当前元素作用域),$element(当前元素),$attrs(当前元素的属性对象),$transclude(后面介绍这个变量,感兴趣的自己去谷歌)。

    require

     这个对象表示需要另外一个directive B(directive之间的通信)并且将会注入directive B所在的controller到linking function中,它的值一般是'xxxController'或者'^xxxController',表示这个directive需要使用directive B的controller属性中的API。

    restrict

    限制directive在html中作用的方式:

    'E' element name,表示以元素的形式在html中作用,例如<my-directive></my-directive>

    'A' attribute ,表示以属性的方式作用在html中,例如 <div my-directive='exp'></div>

    'C' class ,表示以class的形式在html中作用,例如<div class='my-directive : exp ;'></div>

    'M' 以注释的方式在html中作用,例如<!-- directive: my-directive exp -->

    当然,以上也可以组合使用,表示逻辑and。例如 restrict : 'EA',

    template 

    模板代替directive的元素的内容(默认),也可以完全代替元素本身(当replace值为true时有效),也可以用来封装directive的元素的内容(当transclude的值为true时有效)。

    取值:

    • A string. For example <div red-on-hover>{{delete_str}}</div>.
    • A function which takes two arguments tElement and tAttrs (described in the compile function api below) and returns a string value.

    templateUrl

    模板加载地址,异步加载。

    replace

    取值为true时,模板将会取代directive的元素;取值为false,模板将会取代directive的元素的内容。

    transclude

    一般情况下取值有三种true,'element',{...},通常用到前两种。

    当取值为true时, transclude the content (i.e. the child nodes) of the directive's element.举个例子:

    比如说你有一个申明transclude :true的directive叫做my-transclude-true,如下:

    <div>
      <my-transclude-true>
        <span>{{ something }}</span>
        {{ otherThing }}
      </my-transclude-true>
    </div>
    

      当它被编译之后,就会变成如下:

    <div>
      <my-transclude-true>
        <!-- transcluded -->
      </my-transclude-true>
    </div>
    

     my-transclude-true这个directive的内容content(子节点),即'<span>{{something..',将在这个directive中 可用。

    再比如说你有一个申明transclude :'element'的directive叫做my-transclude-element,如下:

    <div>
      <my-transclude-element>
        <span>{{ something }}</span>
        {{ otherThing }}
      </my-transclude-element>
    </div>
    

      被编译之后,就会变成如下:

    <div>
       <!-- transcluded -->
    </div>
    

      这里,它的整个元素包括它的子节点都将在这个directive中可用。当transclude这个属性被申明为'element'时,directive中的template属性将会失去作用。

    最后一个重要的属性:link

    这个属性只有在compile这个属性未定义时才能使用。

    一般的语法糖:link : function (scope,iAttrs,iElement,controller){...}

    link function的作用:Programmatically modify resulting DOM element instances, add event listeners, and set up data binding.以编程方式修改生成的DOM元素实例,添加事件监听器,设置数据绑定。这是整个directive逻辑放的最多的地方。

    下面说说这个函数的参数含义:

    scope  directive用来注册监听事件registering watches的作用域;

    iElement  调用这个directive的实例的元素,比如:angular.module('app',[]).directive('myDirective',function(...){template :'<div data='data'><ul></ul></div>',replace:true});这个directive的元素就是'<div><ul></ul></div>',只有在postlink函数中处理元素的子节点'<ul></ul>'才是安全的,因为子节点已经被link了。(https://docs.angularjs.org/api/ng/service/$compile #link)

    iAttrs 调用这个directive的实例的元素的属性,如上为[data],是一个属性列表集合。

    controller:这个diective所需要的controller实例,通常在require这个属性后面已经写明。

    以上大概就是平时开发过程中常用到的几个属性。

    后面要续写的内容预知:

    1.嵌套directive之间的通讯(即directive之间的交互);

    2.directive与controller之间的数据传递和通信;

    3.controller与controller之间的数据传递和通信。

  • 相关阅读:
    WordPress Contact Form插件‘cntctfrm_contact_emai’参数跨站脚本漏洞
    WordPress Pretty Link插件跨站脚本漏洞
    WordPress Responsive Logo Slideshow插件多个HTML注入漏洞
    WordPress Mingle Forum插件多个SQL注入漏洞
    WordPress Car Demon插件多个HTML注入漏洞
    WordPress Marekkis Watermark 跨站脚本漏洞
    WordPress Mingle Forum插件跨站脚本漏洞
    WordPress Contact Form插件‘contact_form.php’跨站脚本漏洞
    WordPress WPTable Reloaded插件 ‘id’参数跨站脚本漏洞
    遇到困难沟通一下
  • 原文地址:https://www.cnblogs.com/brancepeng/p/5407227.html
Copyright © 2011-2022 走看看