1.基础知识

directive()接受两个参数

· name:字符串,指令的名字

· factory_function:函数,指令的行为

应用启动时,以name作为该应用的标识注册factory_function返回的对象。在factory_function中,可以设置一些选项来改变指令的行为。

1. restrict (string)

该属性用于定义指令以什么形式被使用,这是一个可选参数,该选项默认为A。 
也就是元素(E)、属性(A)、类(C)、注释(M)

· E(元素)

<my-directive></my-directive>

· A(属性,默认值)

<div my-directive="expression"></div>

· C(类名)

<div class="my-directive:expression;"></div>

· M(注释)

<--directive:my-directive expression-->

2. priority (Number)

也就是优先级,默认为0。
在同一元素上声明了多个指令时,根据优先级决定哪个先被调用。 
如果priority相同,则按声明顺序调用。
另外,no-repeat是所有内置指令中优先级最高的。

3. terminal (Boolean)

终端? 而且还是Boolean? 其实terminal的意思是是否停止当前元素上比该指令优先级低的指令。 但是相同的优先级还是会执行。
比如,我们在my-directive的基础上再加一个指令:

.directive('momDirective',function($rootScope){

return{

priority:3,

terminal:true

};

})

调用发现my-directive不会生效:

<div mom-directive my-directive="content" ></div>

4. template (String/Function)

template也是可选的。
String类型时,template可以是一段HTML。
Function类型时,template是一个接受两个参数的函数,分别为:

· tElement

· tAttrs

函数返回一段字符串作为模板。

5. templateUrl (String/Function)

这个就和上面的template很像了,只不过这次是通过URL请求一个模板。 String类型时,templateURL自然是一个URL。 Function类型时返回一段字符串作为模板URL。

6. replace (Boolean/String)

默认值为false

<my-directive></my-directive>

replace为true时,输出:

<p>Kavlez</p>

replace为false时,输出:

<my-directive><p>Kavlez</p></my-directive>

7. transclude (Boolean)

该选项默认为false,翻译过来叫'嵌入',感觉还是有些生涩。template和scope已经可以做很多事情了,但有一点不足。比如在原有元素的基础上添加内容,transclude的例子如下:

<body ng-app="myApp">

<textarea ng-model="content"></textarea>

<div my-directive title="Kavlez">

<hr>

{{content}}

</div>

</body>

<script type="text/javascript">

var myApp = angular.module('myApp', [])

.directive('myDirective', function() {

return {

restrict: 'EA',

scope: {

title: '@',

content: '='

},

transclude: true,

template: '<h2 class="header">{{ title }}</h2>\

<span class="content" ng-transclude></span>'

};

});

</script>

发现div下的hr并没有被移除,就是这样的效果。注意不要忘了在模板中声明ng-transclude。

8. controller (String/Function)

控制器也可以在指令里定义,比如:

.directive('myDirective', function() {

restrict: 'A',

controller: 'myController'

}).controller('myController', function($scope, $element, $attrs,$transclude) {

//...

})

相同的效果,也可以这样声明:

directive('myDirective', function() {

restrict: 'A',

controller:function($scope, $element, $attrs, $transclude) {

//...

}

});

9. controllerAs (String)

可以从名字和类型看出,这个选项是用来设置控制器的别名的。 
比如这样:

directive('myDirective', function() {

return {

restrict: 'A',

template: '<p>{{ myController.name }}</p>',

controllerAs: 'myController',

controller: function() {

this.name = "Kavlez"

}

};

});

10. compile (Object/Function)

compile和link,这两个选项关系到AngularJS的生命周期。

先在这里简单记录一下我对生命周期的认识。

· 应用启动前,所有的指令以文本的形式存在。

· 应用启动后便开始进行compile和link,DOM开始变化,作用域与HTML进行绑定。

· 在编译阶段,AngularJS会遍历整个HTML并处理已声明的指令。

· 一个指令的模板中可能使用了另外一个指令,这个指令的模板中可能包含其他指令,如此层层下来便是一个模板树。

· 在DOM尚未进行数据绑定时对DOM进行操作开销相对较小,这时像ng-repeat之类的指令对DOM进行操作则再合适不过了。

· 我们可以用编译函数访问编译后的DOM,在数据绑定之前用编译函数对模板DOM进行转换,编译函数会返回模板函数。
也就是说,设置compile函数的意义在于:在指令和实时数据被放到DOM中之前修改DOM。 此时完全可以毫无顾虑地操作DOM。

· 接着我们便可以进入下一个阶段,链接阶段。

· 最后,模板函数传递给指令指定的链接函数,链接函数对作用域和DOM进行链接。

接下来我们就试试compile:

<body ng-app="myApp">

<my-directive ng-model="myName"></my-directive>

</body>

<script type="text/javascript">

var myApp = angular.module('myApp', [])

.directive('myDirective', function($rootScope) {

$rootScope.myName = 'Kavlez';

return {

restrict: 'EA',

compile:function(tEle, tAttrs, transcludeFn) {

var h2 = angular.element('<h2></h2>');

h2.attr('type', tAttrs.type);

h2.attr('ng-model', tAttrs.ngModel);

h2.html("hello {{"+tAttrs.ngModel+"}}");

tEle.replaceWith(h2);

}

};

});

</script>

11. scope (Boolean/Object)

默认为false,true时会从父作用域继承并创建一个自己的作用域。
而ng-controller的作用也是从父作用域继承并创建一个新的作用域。
比如这样,离开了自己的作用域就被打回原形了:

<div ng-init="content='from root'">

{{content}}

<div ng-controller="AncestorController">

{{content}}

<div ng-controller="ChildController">

{{content}}

</div>

{{content}}

</div>

{{content}}

</div>

.controller('ChildController', function($scope) {

$scope.content = 'from child';

})

.controller('AncestorController', function($scope) {

$scope.content = 'from ancestor';

})

但不要误解,指令嵌套并不一定会改变它的作用域。
既然true时会从父作用域继承并创建一个自己的作用域,那么我们来试试改为false会是什么样子:

<div ng-init="myProperty='test'">

{{ myProperty }}

<div my-directive ng-init="myProperty = 'by my-directive'">

{{ myProperty }}

</div>

{{ myProperty }}

</div>

.directive('myDirective', function($rootScope) {

return {

scope:false

};

})

显然,结果是三行'by my-directive'。
非true即false? naive!
其实最麻烦的还是隔离作用域,我们稍微改动一下myDirective,改为输出<p>{{内容}}</p>。于是我试着这样定义:

<body ng-app="myApp" >

<p ng-controller="myController">

<div my-directive="I have to leave." ></div>

{{myDirective}}

</p>

</body>

<script type="text/javascript">

var myApp = angular.module('myApp', [])

.directive('myDirective', function($rootScope) {

$rootScope.myDirective = 'from rootScope';

return {

priority:1000,

restrict: 'A',

replace: true,

scope: {

myDirective: '@',

},

template: '<p>{{myDirective}}</p>'

};

})

.controller('myController',function($scope){

$scope.myDirective = 'from controller';

});

</script>

这里需要注意的不是@,重点是隔离作用域。
根据上面的例子输出,template中的{{myDirective}}不会影响到其他作用域。

<input type="text" ng-model="content">

<p ng-controller="myController" >

<div my-directive="{{content}}" ></div>

{{content}}

</p>

发现大家都在一起变,也就是说值是通过复制DOM属性并传递到隔离作用域。
ng-model是个强大的指令,它将自己的隔离作用域和DOM作用域连在一起,这样就是一个双向数据绑定。
如何向指令的隔离作用域中传递数据,这里用了@。或者也可以写成@myDirective,也就是说换个名字什么的也可以,比如我用@myCafe什么的给myDirective赋值也是没问题的,总之是和DOM属性进行绑定。

另外,我们也可以用=进行双向绑定,将本地作用域的属性同父级作用域的属性进行双向绑定。
比如下面的例子中,隔离作用域里的内容只能是'abc' :

<body ng-app="myApp" ng-init="content='abc'">

<p ng-controller="myController" >

<input type="text" ng-model="content">

<div my-directive="content" ></div>

{{content}}

</p>

</body>

<script type="text/javascript">

var myApp = angular.module('myApp', [])

.directive('myDirective', function($rootScope) {

return {

priority:1000,

restrict: 'A',

replace: true,

scope: {

myDirective: '=',

},

template: '<p>from myDirective:{{myDirective}}</p>'

};

})

.controller('myController',function($scope){

$scope.content = 'from controller';

});

</script>

在隔离作用域访问指令外部的作用域的方法还有一种,就是&。
我们可以使用&与父级作用域的函数进行绑定,比如下面的例子:

<body ng-app="myApp">

<div ng-controller="myController">

<table border='1'>

<tr>

<td>From</td>

<td><input type="text" ng-model="from"/></td>

</tr>

<tr>

<td>To</td>

<td><input type="text" ng-model="to"/></td>

</tr>

<tr>

<td>Content</td>

<td><textarea cols="30" rows="10" ng-model="content"></textarea></td>

</tr>

<tr>

<td>Preview:</td>

<td><div scope-example to="to" on-send="sendMail(content)" from="from" /></td>

</tr>

</table>

</div>

</div>

</body>

<script type="text/javascript">

var myApp = angular.module('myApp', [])

.controller('myController',function($scope){

$scope.sendMail=function(content){

console.log('content is:::'+content);

}

})

.directive('scopeExample',function(){

return{

restrict:'EA',

scope: {

to: '=',

from: '=' ,

send: '&onSend'

},

template:'<div>From:{{from}}<br>\

To:{{to}}<br>\

<button ng-click="send()">Send</button>\

</div>'

}

})

</script>

Angularjs学习笔记7_directive1的更多相关文章

  1. AngularJs学习笔记--Forms

    原版地址:http://code.angularjs.org/1.0.2/docs/guide/forms 控件(input.select.textarea)是用户输入数据的一种方式.Form(表单) ...

  2. AngularJs学习笔记--expression

    原版地址:http://code.angularjs.org/1.0.2/docs/guide/expression 表达式(Expressions)是类Javascript的代码片段,通常放置在绑定 ...

  3. AngularJs学习笔记--directive

    原版地址:http://code.angularjs.org/1.0.2/docs/guide/directive Directive是教HTML玩一些新把戏的途径.在DOM编译期间,directiv ...

  4. AngularJs学习笔记--Guide教程系列文章索引

    在很久很久以前,一位前辈向我推荐AngularJs.但当时我没有好好学习,仅仅是讲文档浏览了一次.后来觉醒了……于是下定决心好好理解这系列的文档,并意译出来(英文水平不足……不能说是翻译,有些实在是看 ...

  5. AngularJs学习笔记--bootstrap

    AngularJs学习笔记系列第一篇,希望我可以坚持写下去.本文内容主要来自 http://docs.angularjs.org/guide/ 文档的内容,但也加入些许自己的理解与尝试结果. 一.总括 ...

  6. AngularJs学习笔记--html compiler

    原文再续,书接上回...依旧参考http://code.angularjs.org/1.0.2/docs/guide/compiler 一.总括 Angular的HTML compiler允许开发者自 ...

  7. AngularJs学习笔记--concepts(概念)

    原版地址:http://code.angularjs.org/1.0.2/docs/guide/concepts 继续.. 一.总括 本文主要是angular组件(components)的概览,并说明 ...

  8. AngularJS学习笔记2——AngularJS的初始化

    本文主要介绍AngularJS的自动初始化以及在必要的适合如何手动初始化. Angular <script> Tag 下面通过一小段代码来介绍推荐的自动初始化过程: <!doctyp ...

  9. AngularJs学习笔记--Using $location

    原版地址:http://code.angularjs.org/1.0.2/docs/guide/dev_guide.services.$location 一.What does it do? $loc ...

随机推荐

  1. 详解jQuery的选择器

    1.基本选择器 基本选择器是jQuery中最常用的选择器,也是最简单的选择器,它通过元素id.class和标签名等来查找DOM对象.在网页中,每个id名称只能使用一次,class允许重复使用. ♠ # ...

  2. JavaScript中的map方法

    假设有一个函数f(x)=x²;作用在一个数组[1,2,3,4,5,6,7,8,9],通常我们会用遍历的方法来实现. function f(x){ return x * x; } var arr = [ ...

  3. java中为什么要用多线程

    我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread).线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可能和其他线程共享一些资源,比 ...

  4. [BZOJ 4033] 树上染色

    Link: BZOJ 4033 传送门 Solution: 此题用到了计算贡献的方法, 将 多条路径的路径和  $->$ $\sum_{i=1}^{n-1} w[i]*cnt[i]$ 这样我们由 ...

  5. 【kd-tree】bzoj1176 [Balkan2007]Mokia

    裸题不多说,注意在sqrt(n*log(n))次插入后重构树以保持深度. #include<cstdio> #include<cmath> #include<algori ...

  6. Scala零基础教学【21-40】

    第24讲:Scala中SAM转换实战详解 SAM:single abstract method 单个抽象方法   我们想传入一个函数来指明另一个函数具体化的工作细节,但是重复的样板代码很多. 我们不关 ...

  7. 对象数组的初始化:null reference

    今天写代码的时候,发现我写的对象数组,只声明,而没有初始化,所以记录一下这个问题:null reference. Animals [] an=new Animals[5];//这只是个对象类型数组的声 ...

  8. Jquery的Split二次分割

    <script type="text/javascript">var str="Q1#k1:Q2#k2"var str2=str.split(':' ...

  9. 微信 JS SDK 的 chooseImage 接口在部分安卓机上容易造成页面刷新

    该问题的症状是,当调用 chooseImage 接口并选择拍照,选择照片确定之后,然后从相机返回后,当前web页面就刷新了一次,导致拍照的图片无法选择上传:但是如果直接从相册中选择图片,则不会出现这个 ...

  10. golangWEB框架gin学习之获取get参数

    原文地址:http://www.niu12.com/article/40package main import ( "fmt" "github.com/gin-gonic ...