Benjamin - 专注前端开发和用户体验

NGJS-6 指令(Directives)-2

AngularJS教程 Benjamin 2193℃ 0评论

七、配置属性template

可能的替换方式:

1. 替换指令元素的内容
2. 替换指令元素自身(如果replace: true)
3. 包裹指令元素的内容(如果transclude: true)

可取值:

1. String: HTML字符串,可以包含指令和表达式
2. Function: function(tElem, tAttrs) {
return string;
}

tElem: 当前指令元素(jQLite 对象,如果引入jQuery为jQuery对象)。
tAttrs: 当前指令元素包含的属性

八、配置属性templateUrl

templateUrl和template相似,但它通过URL异步加载模板。因为模板异步加载,编译器将暂停编译该元素上的指令,直到模板加载完成。在此期间,会继续编译该元素的兄弟元素、父元素。

编译器不会暂停整个编译来等待模板加载完成,因为这将导致整个应用“stalling”直到所有的模板异步加载完成。即使一个深度嵌套的包含”templateUrl”的指令也不会。

可以给”templateUrl”指定一个URL字符串,或者一个回调函数,该函数包含tElement,tAttrs两个参数,返回一个url字符串,用来异步加载模板。

Note: 如果你的模板里含有js脚本或者引用,不会被执行,但是会被一并嵌入其中。如果用Firefox开发版来运行,控制台会提示”junk after document element”。看下面实例:

<div ng-app="myApp">
	<div ng-my-a id="demo">我是指令里的内容</div>
</div>
<script type="text/javascript">
	angular.module('myApp', [])
	.directive('ngMyA', function() {
		return {
			restrict: 'A',
			templateUrl: function(tElem, tAttrs) {
				tElem.css({
					backgroundColor: "#ccc",
					border: "1px solid #f00"
				});
				return "getData.html";
			}
		};
	})
</script>

九、配置属性link

This property is used only if the `compile` property is not defined
“link”属性仅用于”compile”属性没有定义情况下。link函数主要职责是处理DOM监听以及DOM更新。
默认配置对象中有两种方式:
// link: {
// pre: function preLink(scope, iElement, iAttrs, controller) { … },
// post: function postLink(scope, iElement, iAttrs, controller) { … }
// }
// or
// link: function postLink( … ) { … }

包含的参数:
function link(scope, iElement, iAttrs, controller, transcludeFn) { … }

scope: 当前作用域,当配置属性没有设置scope时,作用域为父scope。
iElement: 使用该指令的元素
iAttrs: 使用该指令的元素的属性
controller: 一个控制器实例,如果元素上至少一个指令定义了一个控制器,那么该控制器可以在所有指令间共享,并允许控制器作为多个指令间的通信渠道。

transcludeFn:A transclude linking function pre-bound to the correct transclusion scope

Pre-linking function:

Executed before the child elements are linked. Not safe to do DOM transformation since the compiler linking function will fail to locate the correct elements for linking.

Post-linking function:
Executed after the child elements are linked.

Note that child elements that contain `templateUrl` directives will not have been compiled and linked since they are waiting for their template to load asynchronously and their own compilation and linking has been suspended until that occurs.

It is safe to do DOM transformation in the post-linking function on elements that are not waiting for their async templates to be resolved.

十、配置属性compile

function compile(tElement, tAttrs, transclude) { … }
compile函数在link函数被执行之前用来处理模板DOM转换。因为大多数指令不做
模板转换,它经常不被使用。compile函数接受以下参数:

tElement:指令所在的元素
tAttrs: 元素上赋予的属性集合
transclude:[*DEPRECATED*!] A transclude linking function: function(scope, cloneLinkingFn)

要注意的是compile函数不能访问scope,并且必须返回一个link函数。但是如果没有设置compile函数,你可以正常地配置link函数,(有了compile,就不能用link,link函数由compile返回)。compile函数可以写成如下的形式:

<script type="text/javascript">
	angular.module('myApp', [])
	.directive('ngMyA', function() {
		return {
			restrict: 'A',
			require: 'aa',
			compile: function(tElement, tAttrs, transclude) {
				return function(scope, iElement, iAttrs, controller, transcludeFn) {

				}
			}
		};
	})
</script>

十一、配置属性require

该属性用来获取另一个指令,并将该指令的控制器注入到link function的第四个参数。可取值指令名称字符串或者字符串数组,如果为一个数组,link function的参数注入顺序和数组对应,如果指令么有找到,或者指令没有对应的控制器,会抛出一个错误。

指令名可以是以下前缀:
(no prefix):在当前指令元素中查找需要的控制器
“?”: 尝试查找需要的控制器,如果没有找到传递null到link function
“^”: 在当前指令元素及它的父亲查找需要的控制器,没有找到会抛出错误
“^^”: 在该指令元素的父亲查找需要的控制器,没有找到会抛出错误
“?^”: “?”和”^”结合
“?^^”: “?”和”^^”结合

十二、配置属性controllerAs

controllerAs用来指定指令范围内的控制器别名。在指令模板中可以通过别名来引用控制器。该指令需要为该配置定义一个scope作用域。当指令被定义为一个组件时使用别名非常有用。

十三、配置属性controller

定义控制器构造函数,控制器在pre-link阶段之前被实例化,它能在不同指令间被共享,这允许指令相互通信和增强彼此的行为。

十四、本文相关实例

实例一:指令实现类似hover事件的行为

<div ng-app="myApp">
	<div ng-my-a id="demo">我是指令里的内容</div>
</div>
<script type="text/javascript">
	angular.module('myApp', [])
	.directive('ngMyA', function() {
		return {
			restrict: 'A',
			link: function(scope, iElem, iAttrs, controller, transcludeFn) {
				iElem
				.css("background-color", "#f0f")
				.css("cursor", "pointer")
				.bind("mouseenter", function() {
					iElem.css("background-color", "#ccc")
				})
				.bind("mouseleave", function() {
					iElem.css("background-color", "#f0f")
				});
			}
		};
	})
</script>

实例二:指令中访问控制器中的数据和方法

<div ng-app="myApp">
	<div ng-controller="FirstController">
		<div ng-my-a>我是指令里的内容</div>
	</div>
</div>
<script type="text/javascript">
	angular.module('myApp', [])

	.controller('FirstController', function($scope) {
		$scope.message = function() {
			alert("Hello World!");
		}
	})

	.directive('ngMyA', function() {
		return {
			restrict: 'A',
			link: function(scope, iElem, iAttrs, controller, transcludeFn) {
				//此处的scope是父scope,指令并没有创建作用域
				iElem
				.css("cursor", "pointer")
				.bind("mouseenter", function() {
					scope.message();
				})
			}
		};
	})
</script>

实例三:实现不同指令间通信

<div ng-app="myApp">
	<ng-self-animal ng-self-name ng-self-sex>Init data</ng-self-animal>
</div>
<script type="text/javascript">
	angular.module('myApp', [])

	.directive('ngSelfAnimal', function() {
		return {
			restrict: 'E',
			controller: function($scope) {
				$scope.data = [];

				this.setName = function() {
					$scope.data.push("ngSelfName");
				}

				this.setSex = function() {
					$scope.data.push("ngSelfSex");
				}
			},
			link: function(scope, iElem, iAttrs, controller, transcludeFn) {
				iElem
				.bind('mouseenter', function() {
					iElem.html(scope.data.join());
				})
				.bind('mouseleave', function() {
					iElem.html("Init data");
				})
			}
		};
	})

	.directive('ngSelfName', function() {
		return {
			require: 'ngSelfAnimal',
			link: function(scope, iElem, iAttrs, animalController, transcludeFn) {
				animalController.setName();
			}
		};
	})
	.directive('ngSelfSex', function() {
		return {
			require: 'ngSelfAnimal',
			link: function(scope, iElem, iAttrs, animalController, transcludeFn) {
				animalController.setSex();
			}
		};
	})
</script>

这里我们使用require属性,并在link function注入animalController。实现指令间通信

以上就是本节内容,下一节我们将探讨Directives的scope配置属性。scope内容比较多,也比较重要,将单独作为一节来叙述。如果你对文中所述有疑问,欢迎给我留言。

更多阅读:
Develop ->Developer Guide -> HTML Compiler
Develop ->Developer Guide -> Directives

喜欢 (2)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(1)个小伙伴在吐槽