Angularjs学习笔记10_directive3

1.      restrict

M 使用模板 A 属性扩展

2.      templatetemplateUrl$templateCache

模板缓存

//注射器加载完所有模块时,此方法执行一次

myModule.run(function($templateCache){

         $templateCache.put("hello.html","<div>Hello everyone!!!!!!</div>");

});

myModule.directive("hello", function($templateCache) {

    return {

        restrict: 'AECM',

        template: $templateCache.get("hello.html"),

        replace: true

    }

});

3.      replace / transclud

myModule.directive("hello", function() {

    return {

             restrict:"AE",

             transclude:true,

             template:"<div>Hello everyone!<div ng-transclude></div></div>"  把原来内容放在<div ng-transclude>

    }

});

指令之间可以相互嵌套

4.       Comilelink  操作元素,添加css,绑定事件

执行机制

加载   ng-app,确定边界

编译   遍历dom,查找所有指令,根据指令的templateraplacetransclue 转换DOM结构,

        如果存在Comile就执行,自己编写的Comile要执行默认的Comile

连接   每条指令的link会被执行,

       操作dom 如绑定,添加监听,事件

        元素绑定作用域

Comile 对模板本身转化,仅在编译阶段只执行一次  

Link    负责模板和视图动态关联

       对指令的每个实例都执行一次

       作用域在连接阶段才会被绑定到编译后的link函数上

5.      指令和控制器调用

控制器里放公共模块(指令) ,模块(指令)调用各自控制器里的方法。

<body ng-app="MyModule">

          <div ng-controller="MyCtrl">

                   <loader howToLoad="loadData()"> 滑动加载 </loader>  通过自定义属性传递自己特定方法

          </div>

          <div ng-controller="MyCtrl2">

                   <loader howToLoad="loadData2()"> 滑动加载 </loader>

          </div>

</body>

<script>

var myModule = angular.module("MyModule", []);

myModule.controller('MyCtrl', ['$scope', function($scope){

$scope.loadData=function(){

          console.log("加载数据中...");

    }

}]);

myModule.controller('MyCtrl2', ['$scope', function($scope){

    $scope.loadData2=function(){

        console.log("加载数据中...22222");

    }

}]);

myModule.directive("loader", function() {

    return {

    restrict:"AE",

    link:function(scope,element,attrs){

              element.bind('mouseenter', function(event) {            绑定鼠标事件

                       //scope.loadData();

                       // scope.$apply("loadData()");

                       // 注意这里的坑,howToLoad会被转换成小写的howtoload

                       scope.$apply(attrs.howtoload);  一定的用小写

              });

        }

    }

});

</script>

6.      指令和指令调用

         通过指令内部方法暴露在controller里给外面调用,通过依赖,注入

a.指令的方法放在controller link

如果指令的一些方法暴露给外部使用,则把方法放在controller link是处理指令内部事务的,如绑定

b.独立scope作用域

c.require: '^superman'   本指令依赖superman指令

d.公用模块(指令),扩展属性模块(指令

<supermanstrength>动感超人---力量</superman>

<superman strength speed>动感超人2---力量+敏捷</superman>

<superman strength speed light>动感超人3---力量+敏捷+发光</superman>

var myModule = angular.module("MyModule", []);

myModule.directive("superman", function() {

    return {

        scope: {},                                   创建独立作用域每个模块有自己独立的作用域

        restrict: 'AE',

        controller: function($scope) {          模块内部的控制,为外部使用      

            $scope.abilities = [];                      添加属性集合

            this.addStrength = function() {              addStrength,暴露给外面的方法,strength 添加的属性

                $scope.abilities.push("strength");

            };

            this.addSpeed = function() {

                $scope.abilities.push("speed");

            };

            this.addLight = function() {

                $scope.abilities.push("light");

            };

        },

        link: function(scope, element, attrs) {

            element.addClass('btn btn-primary');        添加样式

            element.bind("mouseenter", function() {      绑定事件,绑定数据

                console.log(scope.abilities);

            });

        } 

                   

    }

});

myModule.directive("strength", function() {

    return {

        require: '^superman',                     本指令依赖superman指令,link里就有supermanCtrl参数

        link: function(scope, element, attrs, supermanCtrl) { 

            supermanCtrl.addStrength();     自动注射到link函数里,可以调用superman里暴露的addStrength

        }

    }

});

myModule.directive("speed", function() {

    return {

        require: '^superman',

        link: function(scope, element, attrs, supermanCtrl) {

            supermanCtrl.addSpeed();

        }

    }

});

myModule.directive("light", function() {

    return {

        require: '^superman',

        link: function(scope, element, attrs, supermanCtrl) {

            supermanCtrl.addLight();

        }

    }

});

7.      scope绑定策略  

指令独立scope,指令间相互不影响 

属性绑定,对象绑定,方法绑定

@ 绑定字符串的,把当前属性做字符串传递,可绑定来自外层的scope,在属性值中插入{{}}

         <body ng-app="MyModule">

                  <div ng-controller="MyCtrl">

                          <drink flavor="{{ctrlFlavor}}"></drink>        

……

myModule.controller('MyCtrl', ['$scope', function($scope){

         $scope.ctrlFlavor="百威";

}])

myModule.directive("drink", function() {

    return {

             restrict:'AE',

        scope:{

                flavor:'@'

        },

        template:"<div>{{flavor}}</div>"

        // link:function(scope,element,attrs){

        //    scope.flavor=attrs.flavor;

        // }

    }

});

= 于父scope双向绑定 ,调用父层scope

         <body ng-app="MyModule">

                  <div ng-controller="MyCtrl">

                          Ctrl: <input type="text" ng-model="ctrlFlavor"> <br>

                          Directive: <drink flavor="ctrlFlavor"></drink>  <br>

                ……

myModule.controller('MyCtrl', ['$scope', function($scope){

         $scope.ctrlFlavor="百威";

}])

myModule.directive("drink", function() {

    return {

             restrict:'AE',

        scope:{

                flavor:'='

        },

        template:'<input type="text" ng-model="flavor"/>'

    }

});

& 传递一个来自父层 scope的函数,稍后调用

<div ng-controller="MyCtrl">

                  <greeting greet="sayHello(name)"></greeting>

                  <greeting greet="sayHello(name)"></greeting>

</div>

myModule.controller('MyCtrl', ['$scope', function($scope){

         $scope.sayHello=function(name){

                  alert("Hello "+name);

         }

}])

myModule.directive("greeting", function() {        模板上绑定控制器的方法

    return {

             restrict:'AE',

        scope:{

                greet:'&'

        },

        template:'<input type="text" ng-model="userName" /><br/>'+

                          '<button class="btn btn-default" ng-click="greet({name:userName})">

Greeting</button><br/>'

    }

});

8.      内置指令  

Form  可嵌套,自动校验,input扩展,样式扩展,输入项校验器

                      <form name="form" class="css-form" novalidate>

                               Name: <input type="text" ng-model="user.name" name="uName" required /><br/>

                               E-mail: <input type="email" ng-model="user.email" name="uEmail" required /><br/>

                               <div ng-show="form.uEmail.$dirty && form.uEmail.$invalid">

                                       Invalid:

                                       <span ng-show="form.uEmail.$error.required">Tell us your email.</span>

                                       <span ng-show="form.uEmail.$error.email">This is not a valid email.</span>

                               </div><br/>

                               Gender: <input type="radio" ng-model="user.gender" value="male" />

                                Male  <input type="radio" ng-model="user.gender" value="female" /><br/>

                               Female <input type="checkbox" ng-model="user.agree" name="userAgree" required />

                               I agree: <input ng-show="user.agree" type="text" ng-model="user.agreeSign" required />

                               <div ng-show="!user.agree || !user.agreeSign">

                                       Please agree and sign.

                               </div>

                               <button ng-click="reset()" ng-disabled="isUnchanged(user)">RESET</button>

                               <button ng-click="update(user)" ng-disabled="form.$invalid || isUnchanged(user)">SAVE</button>

                      </form>

function Controller($scope) {

         $scope.master = {};

         $scope.update = function(user) {

                  $scope.master = angular.copy(user);

         };

         $scope.reset = function() {

                  $scope.user = angular.copy($scope.master);

         };

         $scope.isUnchanged = function(user) {

                  return angular.equals(user, $scope.master);

         };

         $scope.reset();

}

Ngbind

事件处理

9.      自定义指令

<div ng-controller='SomeController'>

<expander class='expander' expander-title='title'>     自定义指令 属性 及属性值

                  {{text}}

</expander>

</div>

var expanderModule=angular.module('expanderModule', []);

expanderModule.directive('expander', function() {

         return {

                  restrict : 'EA',

                  replace : true,

                  transclude : true,

                  scope : {

                          title : '=expanderTitle'                   title关联expander-title 的值对象   

                  },

                  template : '<div>'

                                    + '<div class="title" ng-click="toggle()">{{title}}</div>'          使用link里定义函数

                                    + '<div class="body" ng-show="showMe" ng-transclude></div>' 

                                    + '</div>',

                  link : function(scope, element, attrs) {

                          scope.showMe = false;                    

                          scope.toggle = function() {

                                   scope.showMe = !scope.showMe;

                          }

                  }

         }

});

expanderModule.controller('SomeController',function($scope) {

    $scope.title = '点击展开';

         $scope.text = '这里是内部的内容。';

});

10.  自定义指令2

两层嵌套,外层accordion内层 expander,根据数组里的expanders 决定创建多少个expander

<accordion>

         <expander class='expander' ng-repeat='expander in expanders' expander-title='expander.title'>

                          {{expander.text}}

         </expander>

</accordion>

 

expModule.controller("SomeController",function($scope) {

         $scope.expanders = [{

                  title : 'Click me to expand',

                  text : 'Hi there folks, I am the content that was hidden but is now shown.'

         }, {

                  title : 'Click this',

                  text : 'I am even better text than you have seen previously'

         }, {

                  title : 'Test',

                  text : 'test'

         }];

});

var expModule=angular.module('expanderModule',[])

expModule.directive('accordion', function() {

         return {

                  restrict : 'EA',

                  replace : true,

                  transclude : true,

                  template : '<div ng-transclude></div>',

                  controller : function() {

                          var expanders = [];

                          this.gotOpened = function(selectedExpander) {

                                   angular.forEach(expanders, function(expander) {

                                            if (selectedExpander != expander) {

                                                     expander.showMe = false;

                                            }

                                   });

                          }

                          this.addExpander = function(expander) {

                                   expanders.push(expander);

                          }

                  }

         }

});

expModule.directive('expander', function() {

         return {

                  restrict : 'EA',

                  replace : true,

                  transclude : true,

                  require : '^?accordion',

                  scope : {

                          title : '=expanderTitle'

                  },

                  template : '<div>'

                                     + '<div class="title" ng-click="toggle()">{{title}}</div>'

                                     + '<div class="body" ng-show="showMe" ng-transclude></div>'

                                     + '</div>',

                  link : function(scope, element, attrs, accordionController) {

                          scope.showMe = false;

                          accordionController.addExpander(scope);

                          scope.toggle = function toggle() {

                                   scope.showMe = !scope.showMe;

                                   accordionController.gotOpened(scope);

                          }

                  }

         }

});

angularUI

http://miniui.com

         表单,布局,导航,列表   重量级组件Form DatePicker Fileupdate Tree DataGrid

http://Sencha.com

posted on 2016-04-13 18:58  dengzy  阅读(244)  评论(0编辑  收藏  举报