zoukankan      html  css  js  c++  java
  • angularjs directive 实例 详解

    前面提到了angularjs的factory,service,provider,这个可以理解成php的model,这种model是不带html的,今天所说的directive,也可以理解成php的model,也可以理解成插件,只不过这种model是带html的,例如:php的分页函数。

    一,angularjs directive的常用格式,以及参数说明

    1,直接return

    phonecatDirectives = angular.module('phonecatDirectives', []);  
      
    phonecatDirectives.directive('directiveName', function($inject) {  
      
       return {  
         template: '<div></div>',  
      
         replace: false,  
      
         transclude: true,  
      
         restrict: 'E',  
      
         scope: { ... },  
      
          controller: function($scope, $element){ .... },     
      
          compile: function(tElement, tAttrs, transclude) {  
           return {  
             pre: function preLink(scope, iElement, iAttrs, controller) { ... },  
             post: function postLink(scope, iElement, iAttrs, controller) { ... }  
           }  
         },  
      
         link: function(scope, iElement, iAttrs) { ... }  
       };  
    });  

    2,定义一个js的域

    ar phonecatDirectives = angular.module('phonecatDirectives', []);  
      
    phonecatDirectives.directive('directiveName', function($inject) {  
      
       var mydi = {  
         template: '<div></div>',  
          ..................... ,  
         link: function(scope, iElement, iAttrs) { ... }  
       };  
      
       return mydi;  
    }); 

    3,angularjs directive 对像参数说明

    name - 当前scope的名称,注册时可以使用默认值(不填)。


    priority(优先级)- 当有多个directive定义在同一个DOM元素时,有时需要明确它们的执行顺序。这属性用于在directive的compile function调用之前进行排序。如果优先级相同,则执行顺序是不确定的(经初步试验,优先级高的先执行,同级时按照类似栈的“后绑定先执行”。另外,测试时有点不小心,在定义directive的时候,两次定义了一个相同名称的directive,但执行结果发现,两个compile或者link function都会执行)。


    terminal(最后一组)- 如果设置为”true”,则表示当前的priority将会成为最后一组执行的directive。任何directive与当前的优先级相同的话,他们依然会执行,但顺序是不确定的(虽然顺序不确定,但基本上与priority的顺序一致。当前优先级执行完毕后,更低优先级的将不会再执行)。


    scope - 如果设置为:

    true - 将为这个directive创建一个新的scope。如果在同一个元素中有多个directive需要新的scope的话,它还是只会创建一个scope。新的作用域规则不适用于根模版(root of the template),因此根模版往往会获得一个新的scope。

    {}(object hash) - 将创建一个新的、独立(isolate)的scope。”isolate” scope与一般的scope的区别在于它不是通过原型继承于父scope的。这对于创建可复用的组件是很有帮助的,可以有效防止读取或者修改父级scope的数据。这个独立的scope会创建一个拥有一组来源于父scope的本地scope属性(local scope properties)的object hash。这些local properties对于为模版创建值的别名很有帮助(useful for aliasing values for templates -_-!)。本地的定义是对其来源的一组本地scope property的hash映射(Locals definition is a hash of local scope property to its source #&)$&@#)($&@#_):

    @或@attr - 建立一个local scope property到DOM属性的绑定。因为属性值总是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)

    =或=expression(这里也许是attr) - 在本地scope属性与parent scope属性之间设置双向的绑定。如果没有指定attr名称,那么本地名称将与属性名称一致。例如<widget my-attr=”parentModel”>,widget定义的scope为:{localModel:’=myAttr’},那么widget scope property “localName”将会映射父scope的“parentModel”。如果parentModel发生任何改变,localModel也会发生改变,反之亦然。(双向绑定)

    &或&attr - 提供一个在父scope上下文中执行一个表达式的途径。如果没有指定attr的名称,那么local name将与属性名称一致。例如<widget my-attr=”count = count + value”>,widget的scope定义为:{localFn:’increment()’},那么isolate scope property “localFn”会指向一个包裹着increment()表达式的function。一般来说,我们希望通过一个表达式,将数据从isolate scope传到parent scope中。这可以通过传送一个本地变量键值的映射到表达式的wrapper函数中来完成。例如,如果表达式是increment(amount),那么我们可以通过localFn({amount:22})的方式调用localFn以指定amount的值(上面的例子真的没看懂,&跑哪去了?)。


    controller - controller 构造函数。controller会在pre-linking步骤之前进行初始化,并允许其他directive通过指定名称的require进行共享(看下面的require属性)。这将允许directive之间相互沟通,增强相互之间的行为。controller默认注入了以下本地对象:

    $scope - 与当前元素结合的scope

    $element - 当前的元素

    $attrs - 当前元素的属性对象

    $transclude - 一个预先绑定到当前转置scope的转置linking function :function(cloneLinkingFn)。(A transclude linking function pre-bound to the correct transclusion scope)


    require - 请求另外的controller,传入当前directive的linking function中。require需要传入一个directive controller的名称。如果找不到这个名称对应的controller,那么将会抛出一个error。名称可以加入以下前缀:

    ? - 不要抛出异常。这使这个依赖变为一个可选项。

    ^ - 允许查找父元素的controller


    restrict - EACM的子集的字符串,它限制directive为指定的声明方式。如果省略的话,directive将仅仅允许通过属性声明:

    E - 元素名称: <my-directive></my-directive>

    A - 属性名: <div my-directive=”exp”></div>

    C - class名: <div class=”my-directive:exp;”></div>

    M - 注释 : <!-- directive: my-directive exp -->


    template - 如果replace 为true,则将模版内容替换当前的HTML元素,并将原来元素的属性、class一并迁移;如果为false,则将模版元素当作当前元素的子元素处理。想了解更多的话,请查看“Creating Widgets”章节(在哪啊。。。Creating Components就有。。。)


    templateUrl - 与template基本一致,但模版通过指定的url进行加载。因为模版加载是异步的,所以compilation、linking都会暂停,等待加载完毕后再执行。


    replace - 如果设置为true,那么模版将会替换当前元素,而不是作为子元素添加到当前元素中。(注:为true时,模版必须有一个根节点)


    transclude - 编译元素的内容,使它能够被directive所用。需要(在模版中)配合ngTransclude使用(引用)。transclusion的优点是linking function能够得到一个预先与当前scope绑定的transclusion function。一般地,建立一个widget,创建isolate scope,transclusion不是子级的,而是isolate scope的兄弟。这将使得widget拥有私有的状态,transclusion会被绑定到父级(pre-isolate)scope中。(上面那段话没看懂。但实际实验中,如果通过<any my-directive>{{name}}</any my-directive>调用myDirective,而transclude设置为true或者字符串且template中包含<sometag ng-transclude>的时候,将会将{{name}}的编译结果插入到sometag的内容中。如果any的内容没有被标签包裹,那么结果sometag中将会多了一个span。如果本来有其他东西包裹的话,将维持原状。但如果transclude设置为’element’的话,any的整体内容会出现在sometag中,且被p包裹)

    true - 转换这个directive的内容。(这个感觉上,是直接将内容编译后搬入指定地方)

    ‘element’ - 转换整个元素,包括其他优先级较低的directive。(像将整体内容编译后,当作一个整体(外面再包裹p),插入到指定地方)


    compile - 这里是compile function,将在下面实例详细讲解


    link - 这里是link function ,将在下面实例详细讲解。这个属性仅仅是在compile属性没有定义的情况下使用。


    三,angularjs directive 实例讲解

    下面的实例都围绕着,上面的参数来展开的

    1,directive声明方式实例

    //directive文件directives.js中定义一个myTest  
    'use strict';  
      
    var phonecatDirectives = angular.module('phonecatDirectives', []);  
      
    phonecatDirectives.directive('myTest', function() {  
        return {  
            restrict: 'ACEM',  
            require: '^ngModel',  
            scope: {  
                ngModel: '='  
            },  
            template: '<div><h4>Weather for {{ngModel}}</h4></div>'  
        }  
    });  
      
    //controller文件controller.js中定义directive1  
    'use strict';  
      
    var dtControllers = angular.module('dtControllers', []);  
      
    dtControllers.controller('directive1',['$scope',  
        function($scope) {  
            $scope.name = 'this is tank test';  
        }  
    ]);  
      
    //在app文件app.js中整合controller,directive  
      
    'use strict';  
      
    var phonecatApp = angular.module('phonecatApp', [  
        'phonecatDirectives',  
        'dtControllers'  
    ]);  
      
    //html文件  
    <script src="../lib/angular/angular.js"></script>  
    <script src="../js/app.js"></script>  
    <script src="../js/controller.js"></script>  
    <script src="../js/directives.js"></script>  
    <body ng-app="phonecatApp">  
        <div ng-controller="directive1">  
            <input type="text" ng-model="city" placeholder="Enter a city" />  
      
            <my-test ng-model="city" ></my-test>  
            <span my-test="exp" ng-model="city"></span>  
            <!-- directive: my-test exp -->  
            <span ng-model="city"></span>  
        </div>  
    </body>  

    上例结果:<!-- directive: my-test exp -->这个不起作用,不知道为什么,尝试了好多方法都不起作用。

    2,template和templateUrl区别与联系

    templateUrl其实根template功能是一样的,只不过templateUrl加载一个html文件,上例中,我们也能发现问题,template后面根的是html的标签,如果标签很多呢,那就比较不爽了。可以将上例中的,template改一下。

    phonecatDirectives.directive('myTest', function() {  
        return {  
            restrict: 'ACEM',  
            require: '^ngModel',  
            scope: {  
                ngModel: '='  
            },  
            templateUrl:'../partials/tem1.html'   //tem1.html中的内容就是上例中template的内容。  
        }  
    });  

    3,scope重定义

    //directives.js中定义myAttr  
    phonecatDirectives.directive('myAttr', function() {  
        return {  
            restrict: 'E',  
            scope: {  
                customerInfo: '=info'  
            },  
            template: 'Name: {{customerInfo.name}} Address: {{customerInfo.address}}<br>' +  
                      'Name: {{vojta.name}} Address: {{vojta.address}}'  
        };  
    });  
      
    //controller.js中定义attrtest  
    dtControllers.controller('attrtest',['$scope',  
        function($scope) {  
            $scope.naomi = { name: 'Naomi', address: '1600 Amphitheatre' };  
            $scope.vojta = { name: 'Vojta', address: '3456 Somewhere Else' };  
        }  
    ]);  
      
    //html中  
    <body ng-app="phonecatApp">  
        <div ng-controller="attrtest">  
            <my-attr info="naomi"></my-attr>  
        </div>  
    </body>  
  • 相关阅读:
    Win8系统 Python安装
    一些安卓开源框架整理
    Android 媒体键监听以及模拟媒体键盘的实现 demo
    android View 自动 GONE 问题
    Android 定时器TimerTask 简单使用
    关于Android studio 相对 eclipse 优点
    Java序列化与反序列化
    android shape的使用 边框
    Android Studio 修改 包名 package name
    Android WebView Long Press长按保存图片到手机
  • 原文地址:https://www.cnblogs.com/lodingzone/p/5443855.html
Copyright © 2011-2022 走看看