一.指令中controller与link的区别
我们都知道在ng的指令中,返回的对象中有两个重要的属性:
// link function { link: function(scope, iElem, iAttrs, ctrl) { ... }, controller: function($scope, $element, $attrs) { ... } }
这两个都可以获取到作用域,元素,属性等引用,也都会执行一次,在我还是个ng菜鸟的时候,当然,现在也还是,当我每次想要扩展个自定义指令时,脑海中总是萦绕着“where the fuck should I put my code?”,在controller,还是link function中呢。
简短的回答是:优先放在 link function 中。当然啦,这要取决于你想要你的代码什么时候运行。
Before compilation? – Controller After compilation? - Link function
另外,他们的基本区别是:
a.控制器可以暴露一个API,而link可以通过require与其他的指令控制器交互
b.所以如果要开放出一个API给其他指令用就写在controller中,否则写在link中
二.执行先后问题
首先,看下面一个很有趣的示例:log-compile指令。
index.html
<!doctype html> <html ng-app="compilation"> <head> <meta charset="utf-8"> <title>Compilation Demo</title> <link rel="stylesheet" href="style.css"> <script src="http://code.angularjs.org/1.1.1/angular.js"></script> <script src="app.js"></script> </head> <body> <div log-compile="parent"> <div log-compile="..child 1"> <div log-compile="....child 1 a"></div> <div log-compile="....child 1 b"></div> </div> <div log-compile="..child 2"> <div log-compile="....child 2 a"></div> <div log-compile="....child 2 b"></div> </div> </div> <!-- LOG --> <pre>{{log}}</pre> </body> </html>
app.js
angular.module('compilation', []) .directive('logCompile', function($rootScope) { $rootScope.log = ""; return { controller: function($scope, $attrs) { $rootScope.log = $rootScope.log + ($attrs.logCompile + ' (controller)\n'); }, compile: function compile(element, attributes) { $rootScope.log = $rootScope.log + (attributes.logCompile + ' (compile)\n'); return { pre: function preLink(scope, element, attributes) { $rootScope.log = $rootScope.log + (attributes.logCompile + ' (pre-link)\n'); }, post: function postLink(scope, element, attributes) { element.prepend(attributes.logCompile); $rootScope.log = $rootScope.log + (attributes.logCompile + ' (post-link)\n'); } }; } }; }) .directive('terminate', function() { return { terminal: true }; });
style.css
div { padding: 5px; margin: 5px; background-color: #EEE; border: 1px solid #BBB; } div > div { background-color: #DDD; } div > div > div { background-color: #CCC; } ol { list-style: decimal; margin-left: 30px; }
运行结果:
通过这个实例,我们可以知道,子级指令的所有 link function :包括 pre 和 post 两个link都会在父级的post link之前被执行,我们通常所说的link function,其实是 post link 的快捷方式罢了。
所以,像下面这个例子中,这样用,是会有问题的:
index.html
<!DOCTYPE html> <html ng-app="plunker"> <head> <meta charset="utf-8" /> <title>AngularJS Plunker</title> <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" /> <link rel="stylesheet" href="style.css" /> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script src="https://code.angularjs.org/1.1.5/angular.js"></script> <script src="app.js"></script> </head> <body ng-controller="MainCtrl"> <example-directive></example-directive> (above should actually say "hi there", not "bar") </body> </html>
app.js
var app = angular.module('plunker', []); app.controller('MainCtrl', function($scope, $element) { }); app.directive('exampleDirective', function() { return { restrict: 'E', template: '<child-directive></child-directive>', controller: function($scope, $element){ // this will not work, since the child directives link // function was not yet run $element.find('pre').text('hi there!'); }, link: function(scope, el){ // the logic really belongs in link, as the child directive // uncomment this line to fix the problem // el.find('pre').text('hi there!') } } }); app.directive('childDirective', function() { return { restrict: 'E', template: '<h1>bar</h1>', replace: true, link: function($scope, $element, attr){ // some awesome jquery pluggin which replaces things and bits $element.replaceWith(angular.element('<pre>' + $element.text() + '</pre>')); } } });
运行结果:
说明 link 在 ctrl 之后执行的一个例子,上面这个例子非常给力,值得学习。
相关推荐
某天一位前端大神问我:你知道angular指令中的controller,compile,link函数有什么不同?然后我就一脸懵逼了….于是决定深入的去探究下。 今天我们来一起了解一下它们有什么不同的地方: 先看一段示例代码 var ag =...
在自定义指令中,我们可能会遇到需要一个指令与另一个指令或者与控制器进行通信的情况。这通常通过`require`属性来实现。`require`属性允许我们在指令内部访问其他指令或控制器的实例。例如,如果我们有一个父指令和...
在AngularJS中,`ng-repeat`指令用于循环遍历数组或对象,生成DOM元素,它在构建可重用和动态的UI组件时非常有用。在本例中,开发者遇到的问题是在`ng-repeat`循环中包含动态HTML,这些HTML中还嵌套了自定义指令。...
AngularJS中的指令通常以`ng-`开头,如`ng-repeat`、`ng-click`等,但也可以自定义不带`ng-`前缀的指令。指令定义包括两个部分:`directiveName`和`directiveDefinition`。例如: ```javascript app.directive('...
在Angular.js中,指令是构建可复用组件和复杂用户界面的核心工具。它们允许开发者扩展HTML,赋予HTML新的语义,以实现动态行为和数据绑定。这篇教程将深入讲解Angular.js指令的一些重要属性,帮助你更好地理解和应用...
在HTML模板中,我们用`tr-ng-grid`指令来创建表格,并将数据源绑定到`grid-data`属性上: ```html <div tr-ng-grid="myData"> ``` **3. 功能特性** - **排序**:`tr-ng-grid`支持列点击进行自动排序,只需在列...
有时候,我们可以将模板直接写入指令定义,就像`unorderedList`示例中的那样,使用`ng-repeat`来遍历数据生成列表。另一种方式是通过`templateUrl`从外部文件加载模板,或者使用函数生成动态模板,这样可以根据元素...
接着,在你的HTML视图中创建一个`<div>`,并使用`ng-grid`指令来渲染表格。 ```javascript var app = angular.module('myApp', ['ngGrid']); app.controller('myCtrl', function($scope) { $scope.myData = [ // ...
1. **指令结构**:一个AngularJS指令通常由多个部分组成,包括`link`函数、`controller`、`template`和`scope`。`link`函数是指令与DOM元素关联的入口,负责处理DOM操作和事件绑定;`controller`可以用于指令内部的...
在自定义指令中,我们可以利用`link`函数来处理DOM元素,并通过正则表达式进行校验。例如,我们创建一个名为`httpValidator`的指令: ```javascript app.directive('httpValidator', function() { return { ...
* ng-model 指令:将用户输入绑定到模型 四、AngularJS数据绑定 * ng-model 指令:将用户输入绑定到模型 * ng-bind 指令:将数据绑定到视图 * 数据绑定机制:AngularJS如何实现数据绑定的 五、AngularJS条件判断 ...
在superman指令之后,文档展示了如何创建三个子指令(strength、speed、light),这些子指令通过require选项声明依赖superman指令,并在link函数中注入superman指令的controller实例,从而调用superman指令中定义的...
在视图层面,ng-table通过指令`ngTable`与HTML元素结合,创建出一个动态表格。我们可以通过设置`data`属性来指定表格的数据源,这通常是一个数组,每个元素代表一行数据。同时,我们可以利用`ngTableParams`对象来...
同时,控制器则是我们绑定数据到视图的地方,它通常通过`ng-controller`指令来创建,并且可以与视图中的数据双向绑定。 当我们需要从控制器调用指令方法时,通常是希望在某种特定事件发生时,执行指令中的特定逻辑...
指令内部可以通过link函数实现指令与DOM的交互,而通过controller属性,指令还可以与控制器进行交互。 #### 2. 控制器的作用和结构 控制器负责定义视图中的数据和方法,这些数据和方法通过$scope对象传递给视图。...
<div ng-controller="myCtrl"> 这是tooltip的内容">悬停我 ``` 6. **自定义样式**:为了使tooltip更具吸引力,我们可以添加CSS来定义其外观。可以创建一个类,如`.tooltip`,并设置位置、颜色、字体等样式。别...
7. **指令控制器**:`controller`属性允许定义一个关联的JavaScript函数,这个函数作为指令的控制器,可以与其他指令或父控制器通信。 8. **模板与 templateUrl**:指令可以通过`template`属性直接定义HTML模板,...
在上述HTML代码中,`ng-app`指定了AngularJS应用的根作用域,`ng-controller`指令用于创建一个作用域控制器。`ng-repeat`指令被用于渲染用户列表,每个用户都可以通过点击编辑按钮来进入编辑状态。此外,还有一个...
在AngularJS中,控制器(Controller)和指令(Directive)之间的交互是实现动态界面和功能的关键。这篇文章将深入探讨如何在AngularJS中实现这种交互。 首先,让我们了解控制器和指令的基本概念。控制器是AngularJS...
它们通过`ng-controller`指令与视图关联,并可以通过依赖注入(Dependency Injection, DI)获取服务。 3. **数据绑定(Data Binding)** AngularJS的数据绑定使得视图和模型之间的同步变得简单。双向数据绑定允许...