在前面文章中提到一旦声明了require,则连接函数具备第四个参数:controller。html
可见require和controller是配合使用的。angularjs
在自定义指令中使用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>
输出:app
Hello World!函数
从这个例子能够看到,在DOM中须要声明d一、d2,若是不声明d1,那么d2在检查require里的'd1'时,就会抛出异常。ui
AngularJs为咱们提供了一些标记,使用它们能够告诉AngularJs怎么查找所require的控制器:this
1,没标记。在当前元素中查找,若是找不到就抛出错误。spa
2,?标记。在当前元素中查找,若是查找不到,不抛出错误,连接函数的第四个参数为null(如上面代码link: function (scope, elem, attrs, d1)中的d1)code
3,^标记。不只在当前元素中查找,还查找其全部父级。若是找不到就抛出错误。orm
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
点击连接去看看(须要FQ):
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会被调用。