上一节简单的介绍了下自定义指令,这里再进行下升级加强一下。这里就涉及到了其他的一些属性:scope、controller、compile、link、controllerAs、require
加强升级
1、scope
我们知道controller中都有一个作用域,指令同样也有自己的作用域。
scope有三种值:
-
false:默认值,
直接用的父Controller的scope,这时指令的scope===controller的scope,共享同一个model模型,所以当指令中改变了model,父controller中用到被修改的数据的地方也会相应改变 -
true:
新建一个作用域,这个scope继承自父controller的scope,这里就是两个scope了,只不过是继承关系,和JavaScript中原型查找类似,查找的时候才能感觉到原型链的存在,修改赋值感受不到原型链的存在,所以指令中修改了model,父controller中不会改变 -
{ } :
当为对象时创建的一个新的与父作用域隔离的独立作用域,不会继承任何其他scope
我们虽然使用了隔离的作用域,不代表我们不可以使用父作用域的属性和方法。我们可以通过向scope的{}中传入特殊的前缀标识符(&、=、@),来进行数据的绑定。
//控制器定义
var myApp = angular.module('myApp', [])
.controller('myAppCtr', ['$scope', function ($scope) {
$scope.items=[{name:'Javascript'},{name:'C#'},{name:'Css'}];
$scope.title='这是自定义指令';
$scope.hello=function(){
console.log('hello world');
};
}])
html中使用
<my-directive items="items" say="hello" title="{{title}}"></directive-scope>
//自定义指令中设置
scope: {
say: '&say',
items: '=items',
title: '@title'
},
- &:通过函数的方式进行绑定,返回的是一个函数,这个函数的返回结果才是父controller中的属性值,例如指令独立作用域中say是一个函数,say()执行后返回的才是controller中的hello,hello是一个方法,要执行它应该是say()()
- =:进行双向数据绑定,可以理解为scope为false时的特殊情况仅仅是一个属性的共享
- @:进行单向数据绑定,且会将绑定的值转为字符串,注意使用时用{{ }}将带绑定的值包裹,同时传递进来的值是只读的,修改不起作用,但修改不会报错
scope内部只能用来接收传递来的父controller中scope的值,不能新建指令自己的属性方法,否则会报错
2、controller
既然创建独立作用域,那我们肯定就需要添加指令自己的属性、方法,这时就需要用到controller了
controller: ['$scope',function ($scope) {
$scope.title += "——测试一下@是只读的吗";
$scope.say()();
$scope.mySay=function(){
console.log('这是指令自己的say方法');
}]
这里依然可以用依赖注入的方式,这里的$scope是这个指令独有的,我们用到了从controller那里传递来的title和say,同时还自定义了一个mySay方法,再重复一边在scope属性中自定义新属性会报错,然后便可在template属性中使用这个新的scope:
template: '<div>正在进行scope独立作用域测试:{{title}}</div>', //猜一猜title最后输出是什么,不知道的动手试试
3、controllerAs
controllerAs就是给定义的指令的controller起一个名字,用于以后使用时方便
controllerAs:myDirectiveCtr
4、require
有时候我们需要两个指令间进行数据交互,就需要一个指令调用另一个指令controller的属性方法,这时就用到controllerAs和require
require有三种写法,
require:'myDirectiveCtr' //表示这个指令和myDirective指令同一级,兄弟关系
require:'^myDirectiveCtr' //表示myDirective指令是它的父级
require:'?myDirectiveCtr' //表示myDirective是可选的,对这个指令来说可有可无
5、link
link属性是一个方法,参数有scope、element、attributes、controller,
link: function(scope,ele,attrs,controller)
{
//这里可进行DOM操作
}
angular不建议在controller中操作DOM,DOM的相关操作要放到指令中。
element是这个指令最终被编译链接后解析出的元素,只不过此时还不是DOM类型,这是一个类似jquery的类型,angular内部封装了一个轻量级的jquery,attrs就是这个元素的属性,controller是这个指令require进来的其他指令的controller,可以直接通过controller.FunName的形式调用另一个指令中的方法
angularjs指令中的compile与link函数详解