Note07--指令

来源:互联网 发布:java synchorized 参数 编辑:程序博客网 时间:2024/05/13 01:13
1. 目录结构:

这里写图片描述
这里写图片描述

2. Restrict:匹配模式    a. 四个选项:AEMC

这里写图片描述

        i. A:attribute        ii. E:element        iii. M:comment            1) 书写时,两端需要加空格;            2) e.g. <!-- directive:hello -->        iv. C:class

这里写图片描述

    b. 推荐使用AE模式,少用CM方式,因为CM会引起混淆或者麻烦;

这里写图片描述

3. Templatecache    a. 当元素被多次重复使用时,使用templatecache缓存元素

这里写图片描述

    b. $templateCache.html
<!doctype html><html ng-app="MyModule">    <head>        <meta charset="utf-8">    </head>    <body>        <hello></hello>    </body>    <script src="framework/angular-1.3.0.14/angular.js"></script>    <script src="$templateCache.js"></script></html>
    c. $templateCache.js
var myModule = angular.module("MyModule", []);//注射器加载完所有模块时,此方法执行一次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    }});
4. Replace:替换指令标签,同时也替换掉子元素    a. Replace.html
<!doctype html><html ng-app="MyModule">    <head>        <meta charset="utf-8">    </head>    <body>        <hello>            <div>这里是指令内部的内容。</div>        </hello>    </body>    <script src="framework/angular-1.3.0.14/angular.js"></script>    <script src="replace.js"></script></html>
    b. Replace.js
var myModule = angular.module("MyModule", []);myModule.directive("hello", function() {    return {        restrict:"AE",        template:"<div>Hello everyone!</div>",        replace:true    } });
5. Transclude:子元素不替换;非常重要!    a. Transclude.html
<!doctype html><html ng-app="MyModule">    <head>        <meta charset="utf-8">    </head>    <body>        <hello>            <div>这里是指令内部的内容。</div>        </hello>    </body>    <script src="framework/angular-1.3.0.14/angular.js"></script>    <script src="transclude.js"></script></html>
    b. Transclude.js
var myModule = angular.module("MyModule", []);myModule.directive("hello", function() {    return {        restrict:"AE",        transclude:true,        template:"<div>Hello everyone!<div ng-transclude></div></div>"    } });
6. 指令执行机制:compile与link    a. Ng-app只能出现一次;    b. 编写指令是可以自定义compile,一般不会自定义compile;        i. 自定义compile,需要调用默认的compile,否则,默认的compile的行为就会被覆盖掉;    c. link:一般用来操作DOM、绑定事件监听器;

这里写图片描述

7. 指令与控制器之间的交互    a. 通过自定义属性,然后调用scope.$apply() 方法    b. Directive&Controller.html
<!doctype html><html ng-app="MyModule">    <head>        <meta charset="utf-8">    </head>    <body>        <div ng-controller="MyCtrl">            <loader howToLoad="loadData()">滑动加载</loader>        </div>        <div ng-controller="MyCtrl2">            <loader howToLoad="loadData2()">滑动加载</loader>        </div>    </body>    <script src="framework/angular-1.3.0.14/angular.js"></script>    <script src="Directive&Controller.js"></script></html>
    c. Directive&Controller.js
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);            });        }    } });
8. 指令之间的交互    a. Directive&Directive.html
<!doctype html><html ng-app="MyModule"><head>    <meta charset="utf-8">    <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">    <script src="framework/angular-1.3.0.14/angular.js"></script>    <script src="Directive&Directive.js"></script></head><body>    <div class="row">        <div class="col-md-3">            <superman strength>动感超人---力量</superman>        </div>    </div>    <div class="row">        <div class="col-md-3">            <superman strength speed>动感超人2---力量+敏捷</superman>        </div>    </div>    <div class="row">        <div class="col-md-3">            <superman strength speed light>动感超人3---力量+敏捷+发光</superman>        </div>    </div></body></html>
    b. Directive&Directive.js
var myModule = angular.module("MyModule", []);myModule.directive("superman", function() {    return {        scope: {},        restrict: 'AE',        // 指令内部的controller,和外部的controller有区别        controller: function($scope) {            $scope.abilities = [];            this.addStrength = function() {                $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',        link: function(scope, element, attrs, supermanCtrl) {            supermanCtrl.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();        }    }});
    c. directive中的require表示依赖与Superman指令,写了require之后,link函数就可以写第四个参数superctrl。angularJS执行时,会把SupermanCtrl注入到当前指令中,之后就可以调用Superman暴露出来的方法;(superCtrl是形参,参数名无所谓)    d. 逻辑代码什么时候写在指令内部controller里面?什么时候写在link里面?        i. 如果想让指令暴露一些方法给外部调用,则写在controller里面;        ii. link用来处理指令内部的一些事务,比如事件,绑定数据等;9. 独立scope    a. 为指令添加scope即可实现;    b. e.g.        i. isolateScope.html
<!doctype html><html ng-app="MyModule">    <head>        <meta charset="utf-8">        <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">    </head>    <body>        <hello></hello>        <hello></hello>        <hello></hello>        <hello></hello>    </body>    <script src="framework/angular-1.3.0.14/angular.js"></script>    <script src="IsolateScope.js"></script></html>
        ii. isolateScope.js
var myModule = angular.module("MyModule", []);myModule.directive("hello", function() {    return {        restrict: 'AE',        scope:{},        template: '<div><input type="text" ng-model="userName"/>{{userName}}</div>',        replace: true    }});
    c. 绑定策略

这里写图片描述

    d. @方式:传递的是字符串,不是对象        i. ScopeAt.html
<!doctype html><html ng-app="MyModule">    <head>        <meta charset="utf-8">        <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">    </head>    <body>        <div ng-controller="MyCtrl">            <drink flavor="{{ctrlFlavor}}"></drink>        </div>    </body>    <script src="framework/angular-1.3.0.14/angular.js"></script>    <script src="ScopeAt.js"></script></html>
        ii. ScopeAt.js
var myModule = angular.module("MyModule", []);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就可以避免定义link函数;    e. =方式:双向绑定        i. e.g.            1) ScopeEquals.html
<!doctype html><html ng-app="MyModule">    <head>        <meta charset="utf-8">        <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">    </head>    <body>        <div ng-controller="MyCtrl">            Ctrl:            <br>            <input type="text" ng-model="ctrlFlavor">            <br>            Directive:            <br>            <drink flavor="ctrlFlavor"></drink>        </div>    </body>    <script src="framework/angular-1.3.0.14/angular.js"></script>    <script src="ScopeEqual.js"></script></html>
            2) ScopeEquals.js
var myModule = angular.module("MyModule", []);myModule.controller('MyCtrl', ['$scope', function($scope){    $scope.ctrlFlavor="百威";}])myModule.directive("drink", function() {    return {        restrict:'AE',        scope:{            flavor:'='        },        template:'<input type="text" ng-model="flavor"/>'    }});
    f. &方式:传递一个父scope的函数        i. e.g.            1) ScopeAnd.html
<!doctype html><html ng-app="MyModule">    <head>        <meta charset="utf-8">        <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">    </head>    <body>        <div ng-controller="MyCtrl">            <greeting greet="sayHello(name)"></greeting>            <greeting greet="sayHello(name)"></greeting>            <greeting greet="sayHello(name)"></greeting>        </div>    </body>    <script src="framework/angular-1.3.0.14/angular.js"></script>    <script src="ScopeAnd.js"></script></html>
            2) ScopeAnd.js
var myModule = angular.module("MyModule", []);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/>'    }});
10. AngularJS内置指令    a. form表单

这里写图片描述

        i. e.g.            1) formAdv1.html
<!doctype html><html ng-app>    <head>        <script src="framework/angular-1.3.0.14/angular.js"></script>        <script src="FormAdv1.js"></script>    </head>    <body>        <div ng-controller="Controller">            <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>                Gender:<br/>                <input type="radio" ng-model="user.gender" value="male" />                male                <input type="radio" ng-model="user.gender" value="female" />                female<br/>                <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>                <br/>                <button ng-click="reset()" ng-disabled="isUnchanged(user)">                    RESET                </button>                <button ng-click="update(user)" ng-disabled="form.$invalid || isUnchanged(user)">                    SAVE                </button>            </form>        </div>    </body></html>
            2) FormAdv1.js
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();}
        ii. 自定义输入项            1) 避免一些不可预见的行为            2) e.g.                a) FormCustom.html
<!doctype html><html ng-app="form-example2">    <head>        <link href="../bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen">        <script src="framework/angular-1.3.0.14/angular.js"></script>        <script src="FormCustom.js"></script>        <style type="text/css">            div[contentEditable] {                cursor: pointer;                background-color: #D0D0D0;            }        </style>    </head>    <body>        <div>            <div contentEditable="true" ng-model="content" title="Click to edit">Some</div>            <pre>model = {{content}}</pre>        </div>    </body></html>
                b) FormCustom.js
angular.module('form-example2', []).directive('contenteditable', function() {    return {        require : 'ngModel',        link : function(scope, elm, attrs, ctrl) {            // view -> model            elm.bind('keyup', function() {                scope.$apply(function() {                    ctrl.$setViewValue(elm.text());                });            });            // model -> view            ctrl.$render = function() {                elm.html(ctrl.$viewValue);            };            // load init value from DOM            ctrl.$setViewValue(elm.html());        }    };});
    b. 各种事件:ngBlur; ngClick;等等11. 自定义指令    a. e.g. 点击展开或者消失        i. ExpandSimple.html
<html ng-app='expanderModule'>    <head>        <meta http-equiv="content-type" content="text/html; charset=utf-8" />        <link rel="stylesheet" type="text/css" href="ExpanderSimple.css"/>        <script src="framework/angular-1.3.0.14/angular.js"></script>        <script src="ExpanderSimple.js"></script>    </head>    <body>        <div ng-controller='SomeController'>            <expander class='expander' expander-title='title'>                {{text}}            </expander>        </div>    </body></html>
        ii. ExpandSimple.js
var expanderModule=angular.module('expanderModule', []);expanderModule.directive('expander', function() {    return {        restrict : 'EA',        replace : true,        transclude : true,        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) {            scope.showMe = false;            scope.toggle = function() {                scope.showMe = !scope.showMe;            }        }    }});expanderModule.controller('SomeController',function($scope) {    $scope.title = '点击展开';    $scope.text = '这里是内部的内容。';});
        iii. ExpandSimple.css
.expander {border: 1px solid black;    width: 250px;}.expander>.title {    background-color: black;    color: white;    padding: .1em .3em;    cursor: pointer;}.expander>.body {    padding: .1em .3em;}
    b. e.g. 显示多个元素内容        i. Accordion.html
<html ng-app="expanderModule">    <head>        <meta http-equiv="content-type" content="text/html; charset=utf-8" />        <link rel="stylesheet" type="text/css" href="Accordion.css"/>        <script src="framework/angular-1.3.0.14/angular.js"></script>        <script src="Accordion.js"></script>    </head>    <body ng-controller='SomeController' >        <accordion>            <expander class='expander' ng-repeat='expander in expanders' expander-title='expander.title'>                {{expander.text}}            </expander>        </accordion>    </body></html>
        ii. Accordion.js
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);            }        }    }});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'    }];});
    c. E.g. 使用第三方指令库:angularUI        i. Accordion-ngui.html
<!doctype html><html ng-app="MyModule"><head>    <meta charset="utf-8">    <link rel="stylesheet" href="framework/bootstrap-3.0.0/css/bootstrap.css">    <link rel="stylesheet" href="common.css">    <script src="framework/angular-1.3.0.14/angular.js"></script>    <script src="framework/ui-bootstrap-tpls-0.11.0.js"></script>    <script src="Accordion-ngui.js"></script></head><body>    <div class="container">        <div class="row">            <div class="col-md-12">                <div ng-controller="AccordionDemoCtrl">                    <p>                        <button class="btn btn-default btn-md" ng-click="status.open = !status.open">Toggle last panel</button>                        <button class="btn btn-default btn-md" ng-click="status.isFirstDisabled = ! status.isFirstDisabled">Enable / Disable first panel</button>                    </p>                    <label class="checkbox">                        <input type="checkbox" ng-model="oneAtATime">Open only one at a time                    </label>                    <accordion close-others="oneAtATime">                        <accordion-group heading="Static Header, initially expanded" is-open="status.isFirstOpen" is-disabled="status.isFirstDisabled">                            This content is straight in the template.                        </accordion-group>                        <accordion-group heading="{{group.title}}" ng-repeat="group in groups">                            {{group.content}}                        </accordion-group>                        <accordion-group heading="Dynamic Body Content">                            <p>The body of the accordion group grows to fit the contents</p>                            <button class="btn btn-default btn-md" ng-click="addItem()">Add Item</button>                            <div ng-repeat="item in items">{{item}}</div>                        </accordion-group>                        <accordion-group is-open="status.open">                            <accordion-heading>                                I can have markup, too! <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>                            </accordion-heading>                            This is just some content to illustrate fancy headings.                        </accordion-group>                    </accordion>                </div>            </div>        </div>    </div></body></html>
        ii. Accordion-ngui.js
var myModule = angular.module('MyModule', ['ui.bootstrap']);myModule.controller('AccordionDemoCtrl', ['$scope',    function($scope) {        $scope.oneAtATime = true;        $scope.groups = [{            title: 'Dynamic Group Header - 1',            content: 'Dynamic Group Body - 1'        }, {            title: 'Dynamic Group Header - 2',            content: 'Dynamic Group Body - 2'        }];        $scope.items = ['Item 1', 'Item 2', 'Item 3'];        $scope.addItem = function() {            var newItemNo = $scope.items.length + 1;            $scope.items.push('Item ' + newItemNo);        };        $scope.status = {            isFirstOpen: true,            isFirstDisabled: false        };    }])
12. 常见系统的UI    a. ERP类型系统:

这里写图片描述
这里写图片描述
i. http://miniui.com
b. 互联网/电商型系统必备UI组件
i. https://github.com/kissygalleryteam
ii. Angular-UI
iii. www.ngnice.com/showcase/
13. Directive设计思想来源于FLEX

0 0
原创粉丝点击