Javascript angularjs中编译函数和链接函数的区别是什么
有人能简单地解释一下吗 这些文件似乎有点迟钝。我还没有弄清楚什么时候应该用一个来代替另一个。一个对比这两者的例子将非常棒。 编译程序 编译器是一个角度服务,它遍历DOM查找属性。编译过程分为两个阶段Javascript angularjs中编译函数和链接函数的区别是什么,javascript,angularjs,Javascript,Angularjs,有人能简单地解释一下吗 这些文件似乎有点迟钝。我还没有弄清楚什么时候应该用一个来代替另一个。一个对比这两者的例子将非常棒。 编译程序 编译器是一个角度服务,它遍历DOM查找属性。编译过程分为两个阶段 编译:遍历DOM并收集所有指令。结果是一个链接函数 链接:将指令与作用域相结合,生成实时视图。范围模型中的任何更改都会反映在视图中,用户与视图的任何交互都会反映在范围模型中。使范围模型成为真理的单一来源 有些指令,例如为集合中的每个项克隆一次DOM元素。拥有编译和链接阶段可以提高性能,因为克隆的模板
: 如果要进行DOM转换,则应该是
compile
。如果您想添加一些行为改变的功能,应该在链接中添加
- 编译函数-用于模板DOM操纵(即操纵tElement=template元素),因此操纵适用于与指令关联的模板的所有DOM克隆
- 链接函数-用于注册DOM侦听器(即实例作用域上的$watch表达式)以及实例DOM操作(即IEElement=单个实例元素的操作)。
它在克隆模板后执行。例如,在一个 - ,链接函数在该
- 元素的
- 模板(tElement)被克隆(到一个IEElement)后执行。
一个$watch()允许一个指令被通知实例作用域属性的变化(一个实例作用域与每个实例相关联),它允许指令向DOM呈现更新的实例值——通过将内容从实例范围复制到DOM中
请注意,DOM转换可以在编译函数和/或链接函数中完成
大多数指令只需要一个链接函数,因为大多数指令只处理特定的DOM元素实例(及其实例范围)
帮助确定使用哪种方法:考虑编译函数不接收<代码>作用域< /> >参数。(我故意忽略transclude linking函数参数,它接收一个transclude作用域——这是使用的。)因此编译函数不能做任何需要(实例)作用域的事情——你不能$watch任何模型/实例作用域属性,你不能使用实例作用域信息操纵DOM,不能调用在实例范围等上定义的函数
但是,编译函数(如link函数)确实可以访问这些属性。因此,如果DOM操作不需要实例范围,可以使用编译函数。出于这些原因,下面是一个仅使用编译函数的指令的示例。它检查属性,但不需要实例范围来完成其工作
下面是一个也只使用编译函数的指令的示例。该指令只需要转换模板DOM,因此可以使用编译函数
另一种帮助确定使用哪一个的方法:如果在link函数中不使用“element”参数,那么可能不需要link函数
因为大多数指令都有一个链接函数,所以我不会提供任何示例——它们应该很容易找到
请注意,如果需要编译函数和链接函数(或前后链接函数),则编译函数必须返回链接函数,因为如果定义了“compile”属性,“link”属性将被忽略
另见
- Dave Smith的优秀(链接到视频中有关编译和链接的部分)
这是米斯科关于指令的谈话
将编译器函数视为
在模板上工作的东西和允许
更改模板本身,例如,向其添加类或
诸如此类。但真正起作用的是链接功能
将两者绑定在一起的工作,因为链接函数
访问作用域,它是执行一次的链接函数
对于特定模板的每个实例化。所以唯一的
可以放在编译函数中的东西是
在所有实例中都是通用的
我在这件事上撞了几天墙,我觉得有必要再多解释一下
基本上,文档提到分离在很大程度上是一种性能增强。我要重申,编译阶段主要用于在编译子元素之前需要修改DOM的时候
出于我们的目的,我要强调术语,否则会令人困惑:
编译器服务($compile)是处理DOM并在指令中运行各种代码位的角度机制
compile函数是指令中的一位代码,由编译器服务($compile)在特定时间运行
关于编译函数的一些注意事项:
- 您不能修改根元素(您的指令影响的元素),因为它已经从DOM的外部级别编译(编译服务已经扫描了该元素上的指令)
- 如果要添加其他指令
<tp>
<sp>
</sp>
</tp>
tp compile
sp compile
tp pre-link
sp pre-link
sp post-link
tp post-link
<div><span><input type="text"></span><div>
<my-field model="state" name="address"></my-field>
<div><span ng-show="state.visible.address"><input ng-model="state.fields.address" ...>
compile: function(tele, tattr) {
var span = jQuery(tele).find('span').first();
span.attr('ng-show', tattr.model + ".visible." + tattr.name);
...
return {
pre: function() { },
post: function() {}
};
}
directive('d', function($compile) {
return {
// REMEMBER, link is called AFTER nested elements have been compiled and linked!
link: function(scope, iele, iattr) {
var span = jQuery(iele).find('span').first();
span.attr('ng-show', iattr.model + ".visible." + iattr.name);
// CAREFUL! If span had directives on it before
// you will cause them to be processed again:
$compile(span)(scope);
}
});
scope.metadata = {
validations: {
address: [ {
pattern: '^[0-9]',
message: "Address must begin with a number"
},
{ maxlength: 100,
message: "Address too long"
} ]
}
};
scope.state = {
address: '123 Fern Dr'
};
<form name="theForm">
<my-field model="state" metadata="metadata" name="address">
</form>
<form name="theForm">
<div>
<input ng-model="state.address" type="text">
<div ng-show="theForm.address.$error.pattern">Address must begin with a number</input>
...
angular.module('app', []).
directive('my-field', function($compile) {
return {
link: function(scope, iele, iattr) {
// jquery additions via attr()
// remove ng attr from top-level iele (to avoid duplicate processing)
$compile(iele)(scope); // will pick up additions
}
};
});
var app = angular.module('app', []);
app.controller('msg', ['$scope', function($scope){
}]);
app.directive('message', function($interpolate){
return{
compile: function(tElement, tAttributes){
console.log(tAttributes.text + " -In compile..");
return {
pre: function(scope, iElement, iAttributes, controller){
console.log(iAttributes.text + " -In pre..");
},
post: function(scope, iElement, iAttributes, controller){
console.log(iAttributes.text + " -In Post..");
}
}
},
controller: function($scope, $element, $attrs){
console.log($attrs.text + " -In controller..");
},
}
});
<body ng-app="app">
<div ng-controller="msg">
<div message text="first">
<div message text="..second">
<div message text="....third">
</div>
</div>
</div>
</div>