在前面文章中提到一旦声明了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会被调用。

AngularJs自定义指令详解(6) - controller、require的更多相关文章

  1. AngularJs自定义指令详解(1) - restrict

    下面所有例子都使用angular-1.3.16.下载地址:http://cdn.bootcss.com/angular.js/1.3.16/angular.min.js 既然AngularJs快要发布 ...

  2. AngularJs自定义指令详解(2) - template

    一些用于定义行为的指令,可能不需要使用template参数. 当指定template参数时,其值可以是一个字符串,表示一段HTML文本,也可以是一个函数,这函数接受两个参数:tElement和tAtt ...

  3. AngularJs自定义指令详解(5) - link

    在指令中操作DOM,我们需要link参数,这参数要求声明一个函数,称之为链接函数. 写法: link: function(scope, element, attrs) { // 在这里操作DOM} 如 ...

  4. AngularJs自定义指令详解(8) - priority

    priority 默认值为0. 当一个元素上声明两个指令,而且它们的priority一样,谁先被调用?这个需要分情况讲.下面先给个例子: <!DOCTYPE html> <html& ...

  5. AngularJs自定义指令详解(3) - scope

    我们之所以要定义指令,目的是重用指令.假设有这么一个应用场景:在同一个html里使用了两次my-directive,第一个my-directive要展示的是Hello World,第二个my-dire ...

  6. AngularJs自定义指令详解(10) - 执行次序

    代码: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8 ...

  7. AngularJs自定义指令详解(9) - terminal

    例子: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8 ...

  8. AngularJs自定义指令详解(7) - multiElement

    multiElement不太常用,从下面这个例子可以大致看出它的作用: <!DOCTYPE html> <html> <head lang="en"& ...

  9. AngularJs自定义指令详解(4) - transclude

    transclude默认值为false,如果设置 transclude为true,那么相应地,必须在模板代码中加入ng-transclude指令. 先看个例子: <!DOCTYPE html&g ...

随机推荐

  1. 移动端Viewport & 使用rem来开发移动端网站

    Viewport大神 无双 的精彩解释 具体参数各型号是否支持参见: http://www.cnblogs.com/2050/p/3877280.html#commentform 摘录: 移动设备上的 ...

  2. avalon源码分析(转)

    avalon源码分析目录 第一篇 : 关于前端的MVVM架构 第二篇 : 初步接触 第三篇 : 执行流程1 第四篇 :  执行流程2 第五篇 : 整体架构 第六篇 : ViewModel  第七篇 : ...

  3. css左右居中的几种常见方法

    本人是前端的新人,这是第一次写技术博客,各位大大,本文有错误请指正,手中的板砖尽量轻拍,我怕疼~~ 对于水平居中和垂直居中我也用过很多方法,但是有的时候管用有的时候又嗝屁不好使了.涉及到的情况很多,所 ...

  4. web.config中的HttpCookie.HttpOnly属性

    Abstract: The program does not set the HttpCookie.HttpOnly property to true. Explanation: The defaul ...

  5. POJ(2187)用凸包求最远点对

    Beauty Contest http://poj.org/problem?id=2187 题目描述:输入n对整数点,求最距离远的点对,输出他们距离的平方和 算法:拿到这个题,最朴素的想法就是用2层循 ...

  6. datetimepicker一个不错的日历android特效

    datetimepicker一个不错的日历效,选中和选择日历效果都很不错, 实用的时候直接可以把datetimepicker-library这个引入到项目,调用的地方在实现 TimePickerDia ...

  7. [原创.数据可视化系列之六]使用openlyaers进行公网地图剪切

    进行地图开发的过程中,我一般使用天地图或者微软的地图作为地图,因为这两种地图的经纬度偏差最小,基本可以满足用户需求,比如: 不用说,都是全部地图,这也是最常用的一种方法. 但是用户说,我只看大连的地图 ...

  8. 使用oh-my-zsh后导致的卡顿问题

    现象是每次cd和ll时都会被卡住很长时间根本受不了,最后在官方github查明原因是使用的主题会自动获取git信息,可以使用以下命令禁止zsh自动获取git信息,解决卡顿问题 git config - ...

  9. PowerDesigner使用教程

    PowerDesigner是一款功能非常强大的建模工具软件,足以与Rose比肩,同样是当今最著名的建模软件之一.Rose是专攻UML对象模型的建模工具,之后才向数据库建模发展,而PowerDesign ...

  10. android虚拟机

    参考:http://baike.baidu.com/link?url=06bC3y5DSQ7DQ_QbEr6hTfMNpmg2f-39w6FpU69xxkbNoJ5OR4N9xCKoMwMMGTZfF ...