Angular学习心得之directive——require选项的细节

       谈require选项以前,应该先说说controller选项,controller选项容许指令对其余指令提供一个相似接口的功能,只要别的指令(甚至是本身)有须要,就能够获取该controller,将其做为一个对象,并取得其中的全部内容。而require就是链接两个指令的锁链,它能够选择性地获取指令中已经定义好的controller,并做为link函数的第四个参数传递进去,link函数的四个参数分别为scope,element,attr和someCtrl,最后一个就是经过require获取的controller的名字,对于controller的名字,能够在指令中用controllerAs选项进行定义,这是发布控制器的关键.
html

      具体如何获取controller呢?require选项的值能够分别用前缀?、^ 和?^进行修饰,也能够不修饰。数组

      若是不进行修饰,好比require:'thisDirective',那么require只会在当前指令中查找控制器app

      若是想要指向上游的指令,那么就是用^进行修饰,好比require:'^parentDirective',若是没有找到,那就会抛出一个错误。函数

      若是使用?前缀,就意味着若是在当前指令没有找到控制器,就将null做为link的第四个参数;ui

      那么,若是将?和^结合起来,咱们就能够既指定上游指令,又能够在找不到时,不抛出严重的错误。this

      如今问题来了,若是我想指定多于一个指令,那怎么办呢?这时,咱们能够将须要的指令放进一个数组中,例如:require:['^?firstDirective','^?secondDirective','thisDirective'],这不正是依赖注入的形式吗?但要注意一点,若是使用这种写法的话,原先指令中发布的控制器的名字,即controllerAs选项,就失去意义了。此时,咱们在link中调用这些指令的controller的方法变为:先为上边的数组定义一个名字,接着根据其下标号来指定具体的某个指令。相似于:ctrlList[0]。spa

      好,准备工做完毕,接下来经过一个大杂烩的实例来实践require选项。我想实现的效果是,在主指令中,分别指定父级指令中的增长与减小的操做。rest

JS代码:code

增长操做的指令:htm

.directive("add",function(){
        return{
            restrict:'ECMA',
            controller:function($scope){
                $scope.count=0;
                this.addCount=function(){
                    $scope.$apply(function(){
                        $scope.count++;
                    })
                }
            }
        }
    })

减小操做的指令:

.directive("minor",function(){
        return{
            restrict:'ECAM',
            controller:function($scope){
                this.reduceCount=function(){
                    $scope.$apply(function(){
                        $scope.count--;
                    })
                }
               
            }
        }
    })

主指令:

.directive("figure",function(){
        return{
            restrict:'ECMA',
            template:'<button id="add" class="btn btn-default">增长</button>'+
                     '<button id="minor" class="btn btn-danger">减小</button>'+
                     '<div>{{ figureCtrl.temp }}</div>',
            require:['?^add','?^minor'],
            controller:function(){
                this.temp="这个属性被隔离开,可经过controllerAs建立的动态对象调用";
            },
            controllerAs:'figureCtrl',
            link:function(scope,element,attrs,resultCtrl){

            angular.element(document.querySelector('#minor')).on('click',resultCtrl[1].reduceCount);
            angular.element(document.querySelector('#add')).on('click',resultCtrl[0].addCount);
               
        }
        }
    })

HTML代码:

<add minor class="col-md-2 col-md-offset-3">
          <div >次数: {{ count }}</div>
          <figure></figure>
      </add>

运行结果以下图:

注意点:

1.因为add和minor指令都已被注入resultCtrl数组中,因此想调用它们的控制器中的方法,就可使用resultCtrl[i].fun()的方式;

2.更新count的值,但视图是不会改变的,因此须要经过手动$apply()的方式来更新;

3.controllerAs其实是把controller建立为一个对象,而且是隔离的。

大功告成!但仍是但愿大神们能绝不吝啬地对个人文章进行指点和纠正,谢谢!

相关文章
相关标签/搜索