为什么编译多次运行 - Angular Directive

时间:2016-12-13 13:29:35

标签: javascript angularjs angularjs-directive

在下面的代码片段中,我想问一下,如果编译阶段只对指令的所有实例运行一次,为什么我看到console.log(“compile”)运行5次?它应该只运行一次?不是吗?

//module declaration 
var app = angular.module('myApp',[]);

//controller declaration
app.controller('myCtrl',function($scope){
	$scope.name = "Joseph";
});

//app declaration
app.directive('myStudent',function(){
	return{
		template: "Hi! Dear!! {{name}}<br/>",
		compile: function(elem, attr){
			console.log("compile");
		}
	}
});
<body ng-app="myApp" ng-controller="myCtrl"> 
<my-student></my-student> 
<my-student></my-student> 
<my-student></my-student> 
<my-student></my-student> 
<my-student></my-student> 

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular.min.js"></script> 
</body> 

2 个答案:

答案 0 :(得分:1)

HTML编译分三个阶段进行:

  1. $ compile遍历DOM并匹配指令。

    如果编译器发现元素与指令匹配,则该指令将添加到与DOM元素匹配的指令列表中。单个元素可以匹配多个指令。

  2. 一旦识别出与DOM元素匹配的所有指令,编译器就会按优先级对指令进行排序。

    执行每个指令的编译功能。每个编译函数都有机会修改DOM。每个编译函数都返回一个链接函数。这些函数组成一个“组合”链接函数,它调用每个指令的返回链接函数。

  3. $ compile通过调用上一步中的组合链接函数将模板与作用域链接起来。这反过来将调用各个指令的链接函数,在元素上注册监听器,并在配置每个指令时使用作用域设置$ watch。

答案 1 :(得分:1)

来自Angular文档“什么是指令? 在高级别,指令是DOM元素上的标记(例如属性,元素名称,注释或CSS类),它告诉AngularJS的HTML编译器($ compile)将指定的行为附加到该DOM元素(例如,通过事件侦听器) ,甚至转换DOM元素及其子元素。“

因此,当angular编译html时,它会遍历标记,只要发现<my-student></my-student>标记,它就会尝试附加“特定行为”。为了获得每次编译指令所需的特定行为,因为每个指令实例可能具有不同的属性或参数。