sch*_*cki 525 angularjs angularjs-directive
创建指令时,可以将代码放入编译器,链接函数或控制器中.
在文档中,他们解释说:
但是,对我而言,目前尚不清楚哪种代码应该去哪里.
例如:我可以在编译中创建函数并将它们附加到链接中的作用域,还是仅将函数附加到控制器中的作用域?
如果每个指令都有自己的控制器,控制器如何在指令之间共享?控制器是真的共享还是只是范围属性?
gan*_*raj 469
编译:
这是Angular实际编译指令的阶段.对于给定指令的每个引用,只调用一次此编译函数.例如,假设您正在使用ng-repeat指令.ng-repeat必须查找它所附加的元素,提取它所附加的html片段并创建模板函数.
如果您使用过HandleBars,下划线模板或等效模板,就像编译模板以提取模板函数一样.对于此模板函数,您传递数据,该函数的返回值是html,数据位于正确的位置.
编译阶段是Angular中返回模板函数的步骤.角度中的此模板函数称为链接函数.
链接阶段:
链接阶段是将数据($ scope)附加到链接函数的位置,它应该返回链接的html.由于该指令还指定了这个html的去向或更改的内容,因此它已经很好了.这是您要对链接的html进行更改的功能,即已经附加了数据的html.在角度中如果你在链接函数中编写代码,它通常是post-link函数(默认情况下).它是一种在链接函数将数据与模板链接后调用的回调.
控制器:
控制器是您放置某些指令特定逻辑的地方.这个逻辑也可以进入链接函数,但是你必须将该逻辑放在范围内以使其"可共享".问题在于,您将使用指令来破坏范围,而这些东西实际上并不是预期的.那么,如果两个指令希望彼此交谈/相互合作,那么又有什么选择呢?当然,您可以将所有逻辑放入服务中,然后使这两个指令依赖于该服务,但这只会带来一个依赖性.另一种方法是为这个范围提供一个控制器(通常是隔离范围?),然后当该指令"需要"另一个指令时,该控制器被注入另一个指令.有关示例,请参见angularjs.org第一页上的选项卡和窗格.
Tha*_*var 51
A directive允许您以声明方式扩展HTML词汇表以构建Web组件.该ng-app属性是一个指令,所以是ng-controller所有的ng- prefixed attributes.指令可以是attributes,tags甚至class names是comments.
指令如何诞生(compilation和instantiation)
编译:我们将在呈现之前将该compile函数用于manipulateDOM并返回一个link函数(它将为我们处理链接).这也是放置任何需要与所有instancesthis指令共享的方法的地方.
link:我们将使用该link函数注册特定DOM元素上的所有侦听器(从模板克隆)并设置我们对页面的绑定.
如果设置在compile()函数中,它们只会被设置一次(这通常是你想要的).如果在link()函数中设置,则每次将HTML元素绑定到
对象中的数据时都会设置它们.
<div ng-repeat="i in [0,1,2]">
<simple>
<div>Inner content</div>
</simple>
</div>
app.directive("simple", function(){
return {
restrict: "EA",
transclude:true,
template:"<div>{{label}}<div ng-transclude></div></div>",
compile: function(element, attributes){
return {
pre: function(scope, element, attributes, controller, transcludeFn){
},
post: function(scope, element, attributes, controller, transcludeFn){
}
}
},
controller: function($scope){
}
};
});
Run Code Online (Sandbox Code Playgroud)
Compile函数返回pre和post链接函数.在预链接函数中,我们有实例模板以及范围controller,但是模板没有绑定到范围,仍然没有被转换的内容.
Postlink function是post link是最后一个执行的函数.现在transclusion已经完成了the template is linked to a scope,和view will update with data bound values after the next digest cycle.该link选项只是设置post-link功能的快捷方式.
controller:指令控制器可以传递给另一个指令链接/编译阶段.它可以作为在指令间通信中使用的手段注入其他指南.
您必须指定所需指令的名称 - 它应绑定到同一元素或其父元素.该名称可以带有以下前缀:
? – Will not raise any error if a mentioned directive does not exist.
^ – Will look for the directive on parent elements, if not available on the same element.
Run Code Online (Sandbox Code Playgroud)
使用方括号[‘directive1?, ‘directive2?, ‘directive3?]需要多个指令控制器.
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope, $element) {
});
app.directive('parentDirective', function() {
return {
restrict: 'E',
template: '<child-directive></child-directive>',
controller: function($scope, $element){
this.variable = "Hi Vinothbabu"
}
}
});
app.directive('childDirective', function() {
return {
restrict: 'E',
template: '<h1>I am child</h1>',
replace: true,
require: '^parentDirective',
link: function($scope, $element, attr, parentDirectCtrl){
//you now have access to parentDirectCtrl.variable
}
}
});
Run Code Online (Sandbox Code Playgroud)
小智 13
此外,使用控制器与链接功能的一个很好的理由(因为它们都可以访问范围,元素和attrs)是因为您可以将任何可用的服务或依赖项传递到控制器(并以任何顺序),而你不能用链接功能做到这一点.注意不同的签名:
controller: function($scope, $exceptionHandler, $attr, $element, $parse, $myOtherService, someCrazyDependency) {...
Run Code Online (Sandbox Code Playgroud)
与
link: function(scope, element, attrs) {... //no services allowed
Run Code Online (Sandbox Code Playgroud)
Ami*_*imi 10
这是理解指令阶段的一个很好的示例 http://codepen.io/anon/pen/oXMdBQ?editors=101
var app = angular.module('myapp', [])
app.directive('slngStylePrelink', function() {
return {
scope: {
drctvName: '@'
},
controller: function($scope) {
console.log('controller for ', $scope.drctvName);
},
compile: function(element, attr) {
console.log("compile for ", attr.name)
return {
post: function($scope, element, attr) {
console.log('post link for ', attr.name)
},
pre: function($scope, element, attr) {
$scope.element = element;
console.log('pre link for ', attr.name)
// from angular.js 1.4.1
function ngStyleWatchAction(newStyles, oldStyles) {
if (oldStyles && (newStyles !== oldStyles)) {
forEach(oldStyles, function(val, style) {
element.css(style, '');
});
}
if (newStyles) element.css(newStyles);
}
$scope.$watch(attr.slngStylePrelink, ngStyleWatchAction, true);
// Run immediately, because the watcher's first run is async
ngStyleWatchAction($scope.$eval(attr.slngStylePrelink));
}
};
}
};
});
Run Code Online (Sandbox Code Playgroud)
HTML
<body ng-app="myapp">
<div slng-style-prelink="{height:'500px'}" drctv-name='parent' style="border:1px solid" name="parent">
<div slng-style-prelink="{height:'50%'}" drctv-name='child' style="border:1px solid red" name='child'>
</div>
</div>
</body>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
230116 次 |
| 最近记录: |