zoukankan      html  css  js  c++  java
  • AngularJs自定义指令详解(6)

    在前面文章中提到一旦声明了require,则链接函数具有第四个参数:controller。

    可见require和controller是配合使用的。

    在自定义指令中使用controller,目的往往是要封装一些行为,给其他指令使用。下面是一个简单的例子:

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <script src="../lib/angular-1.3.16/angular.min.js"></script>
        <title></title>
        <script language="JavaScript">
            var app = angular.module('myapp',[]);
    
            app.directive('d1',function() {
                return {
                    controller: function ($scope) {
                        this.method1 = function () {
                            return 'World';
                        };
                    }
                }
            });
    
            app.directive('d2',function() {
                return {
                    require: 'd1',
                    link: function (scope, elem, attrs, d1) {
                        scope.greeting = d1.method1();
                    }
                }
            });
        </script>
    </head>
    <body ng-app="myapp">
    <div d1 d2>Hello {{greeting}}!</div>
    </body>
    </html>

    输出:

    Hello World!

    从这个例子可以看到,在DOM中需要声明d1、d2,如果不声明d1,那么d2在检查require里的'd1'时,就会抛出异常。

    AngularJs为我们提供了一些标记,使用它们可以告诉AngularJs怎么查找所require的控制器:

    1,没标记。在当前元素中查找,如果找不到就抛出错误。

    2,?标记。在当前元素中查找,如果查找不到,不抛出错误,链接函数的第四个参数为null(如上面代码link: function (scope, elem, attrs, d1)中的d1)

    3,^标记。不仅在当前元素中查找,还查找其所有父级。如果找不到就抛出错误。

    4,^^标记。只在当前元素的父级中查找。如果找不到就抛出错误。

    5,?^标记。不仅在当前元素中查找,还查找其所有父级。如果查找不到,不抛出错误,链接函数的第四个参数为null

    6,?^^标记。只在当前元素的父级中查找。如果查找不到,不抛出错误,链接函数的第四个参数为null

    我们修改一下上面例子的代码,试验一下第4条:

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <script src="../lib/angular-1.3.16/angular.min.js"></script>
        <title></title>
        <script language="JavaScript">
            var app = angular.module('myapp',[]);
    
            app.directive('d1',function() {
                return {
                    controller: function ($scope) {
                        this.method1 = function () {
                            return 'World';
                        };
                    }
                }
            });
    
            app.directive('d2',function() {
                return {
                    require: '^^d1',
                    link: function (scope, elem, attrs, d1) {
                        scope.greeting = d1.method1();
                    }
                }
            });
        </script>
    </head>
    <body ng-app="myapp">
    <div d1 d2>Hello {{greeting}}!</div>
    </body>
    </html>

    在Chrome浏览器的控制台可以看到错误提示:

    Error: [$compile:ctreq] http://errors.angularjs.org/1.3.16/$compile/ctreq?p0=d1&p1=d2

    点击链接去看看(需要翻墙):

    Error: $compile:ctreq

    Missing Required Controller
    Controller 'd1', required by directive 'd2', can't be found!

    果然找不到!因为d1放在d2所在的div中(当前元素),^^标记要求去父级找,当然没有了。

    在实际应用时,我们往往会require 'ngModel',也就是希望利用AngularJs内置指令ngModel里的方法,而不是自己重新写:

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <script src="../lib/angular-1.3.16/angular.min.js"></script>
        <title></title>
        <script language="JavaScript">
            var app = angular.module('myApp',[]);
    
            app.directive('myDirective',function() {
                return {
                    require: 'ngModel',
                    link: function (scope, elem, attrs, model) {
                        model.$parsers.unshift(function(value) {
                            if (parseFloat(value)<1) {
                                model.$setValidity('test', true);
                                return parseFloat(value).toFixed(2);
                            } else {
                                model.$setValidity('test', false);
                                return undefined;
                            }
                        });
                    }
                }
            });
    
        </script>
    </head>
    <body ng-app="myApp">
    <form name="form1">
         <div> 请输入小于1的一个小数:<input name="input1" type="number" ng-model="aNumber" my-directive />
                保留小数点后2位:{{aNumber}}
         </div>
        <span ng-show="form1.input1.$error.test">这个数并不小于1!</span>
    </form>
    </body>
    </html>

    上面例子就是利用了ngModel里已有的$parser属性和$setValidity方法。

    $parsers里保存了一组function, 每当DOM里数据变化的时候, 这组function会被调用。

  • 相关阅读:
    Jetpack MVVM 高频提问和解答
    Android-Jetpack架构组件-—-Navigation#
    Jetpack明星组件 —ViewModel #
    Android开发把 LiveData 用于事件传递那些坑#
    Android官方架构组件Lifecycle#
    Android架构组件JetPack之Lifecycle#
    Android架构组件JetPack之LiveData的工作原理#
    DataBinding从入门到通透#
    SpringBoot 分包方式多数据源
    SpringBoot与数据访问
  • 原文地址:https://www.cnblogs.com/sagacite/p/4621756.html
Copyright © 2011-2022 走看看