我有以下代码。我希望编译只运行一次,并链接运行5次。
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js" ></script>
<style>.red{color:red;}.blue{background:blue;}</style>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div hello dear> 1 </div>
<div hello dear> 2 </div>
<div hello dear> 3 </div>
<div hello dear> 4 </div>
<div hello dear> 5 </div>
<script>
//module declaration
var app = angular.module("myApp",[]);
//controller declaration
app.controller('myCtrl',function($scope){
//no code
});
//directives declaration
app.directive('hello',function(){
return{
restrict: 'A',
compile: function(tElement, tAttributes){
tElement.addClass("red");
console.log("compiled");
},
}
});
app.directive('dear',function(){
return{
restrict: 'A',
link: function($scope, element, attributes){
element.addClass("blue");
console.log("linked");
}
}
});
</script>
</body>
</html>
期望:
编译运行一次。链接运行5次。
结果:
编译和链接运行5次。
屏幕截图:
参考:
http://www.bennadel.com/blog/2794-when-do-you-need-to-compile-a-directive-in-angularjs.htm
有人可以告诉我为什么编译运行5次(或者,如何只运行一次)?
答案 0 :(得分:1)
编译阶段在每个指令的链接阶段之前,因为您在5个元素上应用了hello
指令,它的预期行为要编译然后链接5次。可以在here找到关于指令与子指令的链接过程的更详细说明。
编译功能
当Angular bootstraps时,每个指令的编译函数只被调用一次。
正式地说,这是执行(源)模板操作的地方,不涉及范围或数据绑定。
首先,这是为了优化目的;考虑以下标记:
<tr ng-repeat="raw in raws">
<my-raw></my-raw>
</tr>
<my-raw>
指令将呈现一组特定的DOM标记。所以我们可以:
允许ng-repeat复制源模板(<my-raw>
),然后修改每个实例模板的标记(在编译函数之外)。
修改源模板以包含所需的标记(在编译函数中),然后允许ng-repeat复制它。
如果raws集合中有1000个项目,则后一个选项可能比前一个项目更快。
执行:
不要:
答案 1 :(得分:1)
这是预期的行为。 看看https://docs.angularjs.org/api/ng/service/ $ compile
每个指令标记都会发生整个流程(编译,控制器,前/后链接)。
这将使您的编译只运行一次:
<hello>
<div dear> 1 </div>
<div dear> 2 </div>
<div dear> 3 </div>
<div dear> 4 </div>
<div dear> 5 </div>
</hello>
虽然在这种情况下,不需要使用编译阶段,只需使用链接
app.directive('hello',function(){
return{
restrict: 'AE',
link: function(scope, iElement){
iElement.children().addClass("red");
console.log("\"compiled\"");
},
}
});
编辑:如果您需要在亲爱的人之前运行hello指令的代码,请将代码放在预链接而不是链接。
.directive('hello', function() {
return {
restrict: 'AE',
compile: function() {
return {
pre: function(scope, iElement) {
iElement.children().addClass("red");
console.log("\"compiled\"");
}
}
},
}
})