指令详解
1.用directive()方法来定义指令
.directive('myDirective',function($timeout,userDefinedService){
return {};
});
该方法接受两个参数:
name(字符串):指令的名字,用来在视图中引用特定的指令
factory_function(函数):该函数返回一个对象,其中定义了指令的全部行为
当AngularJS启动应用时,会把第一个参数当做一个字符串,并以此字符串为名来来注册第二个参数返回的对象。也可以返回一个函数代替对象来定义指令,当返回一个函数时,这个函数通常被称为链接传递函数,利用它可以定义指令的链接功能。但是返回函数会限制定义指令时的自由度。
2.指令可以使用的设置选项
(1)restrict(字符串)
告诉AngularJS这个指令在DOM中可以以何种形式被声明,包括:
E(元素) <my-directive></my-directive>
A(属性,默认值) <div my-directive="expression"></div>
C(类名) <div class="my-directive:expression;"></div>
这些选项可以混合使用,属性时声明指令最常用的方式,因为它能在包括老版本的IE浏览器在内的所有浏览器中正常工作,并且不需要在文档头部注册新的标签。
如何进行选择,通常取决于定义的指令是否包含某个组件的核心行为(E),或者用额外的行为、状态或者其他内容对某个核心组件进行修饰或拓展(A)
当编写的模板还需要在其他指令中使用时,可以将这个模板缓存起来,如:
<hello></hello>
var myApp=angular.module('myApp',[]);
myApp.run(function($templateCache){
$templateCache.put("index1.html","<div>Hello Everyone!</div>");
});
myApp.directive('hello',function($templateCache){
return{
restrict:'AE',
template:$templateCache.get('index1.html'),
repalce:true
}
})
(2)优先级pripority(数值)
如果一个元素上具有两个优先级相同的指令,声明在前面的那个会被优先调用。
ng-repeat是所有指令中优先级最高的,其他的默认值为0,主要是从性能进行考虑的。
(3)terminal(布尔型)
该参数告诉AngularJS停止运行当前元素上比本指令优先级低的指令,但是优先级相同的指令仍会执行。
(4)template(字符串或函数)
必须被设置为以下两种形式:
a一段HTML文本
b一个可以接受两个参数的函数,参数为tElement和tAttrs,并返回一个代表模板的字符串。
模板字符串中必须存在一个跟DOM元素,每一行末尾的反斜线能保证AngularJS正确解析多行字符串。更好的选择是使用templateUrl参数引用外部模板,因为多行文本难以阅读和维护。
(5)templateUrl
可以是两种类型:
a一个代表外部HTML文件路径的字符串
b一个可以接受两个参数的函数,参数为tElement和tAttrs,并返回一个外部HTML文件路径的字符串
调用指令时会在后台通过Ajax来请求HTML模板文件,在本地开发时,需要在后台运行一个本地服务器来从文件系统中加载HTML模板。模板加载是异步的,意味着编译和链接要暂停,等待模板加载完成。
通过Ajax异步加载大量的模板将严重拖慢一个客户端应用的速度,可以提前将模板缓存到一个定义模板的JS文件中。
(6)replace(布尔型)
设置为true意味着模板会被当做子元素插入到调用此指令的元素内部。
<div some-directive></div>
.directive('someDirective',function(){
return{
template:'<div>some stuff here</div>'
};
})
结果:<div some-directive><div>some stuff here</div></div>
加入replace:true后,结果为:<div>some stuff here</div>
(7)scope(布尔型或对象)
scope设置为true时,会从父作用域继承并创建一个新的作用域对象
隔离作用域最主要的应用场景是创建可复用的组件,组件可以在未知上下文中使用,并且可以避免污染所处的外部作用域或不经意的污染内部作用域。创建具有隔离作用域的指令需要将scope属性设置为一个空对象{},这样指令的模板就无法访问外部作用域了。
<div ng-app="myApp"
ng-init="someProperty = 'some data'"></div>
<div ng-init="siblingProperty = 'more data'">
Inside Div Two: {{ aThirdProperty }}
<div ng-init="aThirdProperty = 'data for 3rd property'"
ng-controller="SomeCtrl">
Inside Div Three: {{ aThirdProperty }}
<div ng-controller="SecondCtrl">
Inside Div Four: {{ aThirdProperty }}
<br>
Outside myDirective: {{ myProperty }}
<div my-directive ng-init="myProperty = 'wow, this is cool'">
Inside myDirective: {{ myProperty }}
<div>
</div>
</div>
</div>
angular.module('myApp', [])
.controller('SomeCtrl', function($scope) {
// we can leave it empty, it just needs to be defined
})
.controller('SecondCtrl', function($scope) {
// also can be empty
})
.directive('myDirective', function() {
return {
restrict: 'A',
//scope:true
}
})
结果为:Inside Div Two:
Inside Div Three: data for 3rd property
Inside Div Four: data for 3rd property
Outside myDirective: wow, this is cool
Inside myDirective: wow, this is cool
加上scope:true或scope:{}结果为:Outside myDirective:
Inside myDirective: wow, this is cool
例:
<div ng-conreoller="MainController">
Outside myDirective: {{ myProperty }}
<div my-directive ng-init="myProperty = 'wow, this is cool'">
Inside myDirective: {{ myProperty }}
<div>
</div>
angular.module('myApp', [])
.controller('MainController',function($scope){
})
.directive('myDirective', function() {
return {
restrict: 'A',
scope: true,
priority:100,
template:'<div>Inside myDirective:{{ myProperty }}</div>'
};
})
Outside myDirective:
Inside myDirective:wow, this is cool
例:
<div ng-init="myProperty = 'wow, this is cool'"></div>
Surrounding scope: {{ myProperty }}
<div my-inherit-scope-directive="SomeCtrl">
Inside an directive with inherited scope: {{ myProperty }}
</div>
<div my-directive>
Inside myDirective, isolate scope: {{ myProperty }}
<div>
angular.module('myApp', [])
.directive('myDirective', function() {
return {
restrict: 'A',
scope: {}
};
})
.directive('myInheritScopeDirective', function() {
return {
restrict: 'A',
scope: true
};
})
Surrounding scope: wow, this is cool
Inside an directive with inherited scope: wow, this is cool
Inside myDirective, isolate scope:
(8)绑定策略
使用绑定策略将指令内部的隔离作用域同指令外部的作用域进行数据绑定
a本地作用域属性:@/@attr 将本地作用域同DOM属性的值进行绑定
b双向绑定:=/=attr 将本地作用域上的属性同父级作用域上的属性进行双向绑定
c父级作用域绑定:&/&attr 对这个值进行设置时会生成一个指向父级作用域的包装函数
例:
<div ng-controller="myCtrl">
<drink flavor="{{ctrlFlavor}}"></drink>
</div>
var myApp=angular.module('myApp',[]);
myApp.controller('myCtrl',['$scope',function($scope){
$scope.ctrlFlavor="百威";
}]);
myApp.directive("drink",function(){
return{
restrict:'AE',
template:"<div>{{flavor}}</div>",
link:function(scope,element,attrs){
scope.flavor=attrs.flavor;
}
}
})
相当于:
myApp.directive("drink",function(){
return{
restrict:'AE',
scope:{
flavor:'@'
},
template:"<div>{{flavor}}</div>"
}
})
例:
<div ng-controller="myCtrl">
Ctrl:<br>
<input type="text" ng-model="ctrlFlavor"><br>
Directive:<br>
<drink flavor="ctrlFlavor"></drink>
</div>
var myApp=angular.module('myApp',[]);
myApp.controller('myCtrl',['$scope',function($scope){
$scope.ctrlFlavor="百威";
}]);
myApp.directive("drink",function(){
return{
restrict:'AE',
scope:{
flavor:'='
},
template:'<input type="text" ng-model="flavor" />'
}
})
修改其中一个,另一个会发生改变
(9)transclude(布尔型)
用来创建可复用的组件,典型的例子就是模态对话框或导航栏。
可以将整个模板,包括其中的指令通过嵌入全部传入一个指令中。为了将作用域传递进去,scope参数的值必须通过{}或true设置成隔离作用域。
(10)controller(字符串或函数)
angular.module('myapp',[])
.directive('myDirective',function(){
restrict:'A',
controller:'SomeController'
})
同时要在同一个文件或index.html包含的另一个文件中设置控制器
angular.module('myapp',[])
.controller('SomeController',function($scope,$element,$attrs,$transclude){})
也可以在指令内部通过匿名构造函数的方式来定义一个内联的控制器:
angular.module('myapp',[])
.directive('myDirective',function(){
restrict:'A',
controller:function($scope,$element,$attrs,$transclude){
}
})
可以将任意可以被注入的AngularJS服务传递给控制器,只需将其注入到控制器中,就可以在指令中使用它。一些特殊的服务可以被注入到指令中,包括:
$scope:与指令元素相关联的当前作用域
$element:当前指令对应的元素
$attrs:由当前元素的属性组成的对象
<div id="aDiv" class="box"></div>
{
id:"aDiv",
class:"box"
}
$transclude:嵌入链接函数会与对应的嵌入作用域进行预绑定
3.指令的生命周期
(1)加载阶段:加载angularjs,找到ng-app,确定应用的边界
编译阶段:
遍历DOM,找到所有指令;
根据指令代码中的template,replace,transclude转换DOM结构;
如果有complie函数则调用;
链接阶段:
对每一条指令运行link函数;
link函数一般用来操作DOM,绑定事件监听器,监听数据变化
(2)link函数的应用:
如果指令定义中有require选项,函数签名中会有第四个参数,代表控制器或所依赖的指令额控制器
link:function(scope,element,attrs,SomeController){
}
其中,scope指令用来在其内部注册监听器的作用域,iElement参数代表实例元素,指的是使用此指令的元素,iAttrs参数代表实例属性,是一个由定义在元素上的属性组成的标准化列表,可以在所有指令的链接函数间共享。controller参数指向require选项定义的控制器。
<div ng-controller="myCtrl">
<loader howToLoad="loadData()">滑动加载</loader>
</div>
myApp.directive('loader',function(){
return{
restrict:'AE',
link:function(scope,element,attrs){
element.bind("mouseenter",function(){
//scope.loadData();
scope.$apply("loadData()");
})
}
};
})
在不同的controller中复用指令:
<div ng-controller="myCtrl">
<loader howToLoad="loadData()">滑动加载</loader>
</div>
<div ng-controller="myCtrl2">
<loader howToLoad="loadData2()">滑动加载</loader>
</div>
var myApp=angular.module('myApp',[]);
myApp.controller('myCtrl',['$scope',function($scope){
$scope.loadData=function(){
console.log('数据加载中111');
}
}]);
myApp.controller('myCtrl2',['$scope',function($scope){
$scope.loadData2=function(){
console.log('数据加载中222');
}
}]);
myApp.directive('loader',function(){
return{
restrict:'AE',
link:function(scope,element,attrs){
element.bind("mouseenter",function(){
scope.$apply(attrs.howtoload);
})
}
};
})
指令的复用:
<div class="row">
<div class="col-md-3">
<superman strength>动感超人</superman>
</div>
<div class="col-md-3">
<superman strength speed>动感超人2---力量+敏捷</superman>
</div>
<div class="col-md-3">
<superman strength speed light>动感超人3---力量+敏捷+发光</superman>
</div>
</div>
var myApp=angular.module('myApp',[]);
myApp.directive("superman",function(){
return{
scope:{},
restrict:'AE',
controller:function($scope){
$scope.abilities=[];
this.addStrength=function(){
$scope.abilities.push("strength");
};
this.addSpeed=function(){
$scope.abilities.push("speed");
};
this.addLight=function(){
$scope.abilities.push("light");
};
},
link:function(scope,element,attrs){
element.addClass('btn btn-primary');
element.bind("mouseenter",function(){
console.log(scope.abilities);
});
}
}
});
myApp.directive("strength",function(){
return{
require:'^superman',
link:function(scope,element,attrs,supermanCtrl){
supermanCtrl.addStrength();
}
}
});
myApp.directive("speed",function(){
return{
require:'^superman',
link:function(scope,element,attrs,supermanCtrl){
supermanCtrl.addSpeed();
}
}
});
myApp.directive("light",function(){
return{
require:'^superman',
link:function(scope,element,attrs,supermanCtrl){
supermanCtrl.addLight();
}
}
});
独立scope:
<hello></hello>
<hello></hello>
<hello></hello>
<hello></hello>
var myApp=angular.module('myApp',[]);
myApp.directive("hello",function(){
return{
restrict:'AE',
template:'<div><input type="text" ng-model="username" />
{{username}}</div>',
replace:true
}
})
点击其中一个输入框,所有的输入框及其后面内容都变化。只需加入scope:{},所有的输入框内容互不影响

angularJS 指令二的更多相关文章

  1. angularjs指令(二)

    最近学习了下angularjs指令的相关知识,也参考了前人的一些文章,在此总结下. 欢迎批评指出错误的地方.   Angularjs指令定义的API AngularJs的指令定义大致如下 angula ...

  2. AngularJS学习笔记二:AngularJS指令

    AngularJS 指令: AngularJS 通过被称为 指令 的新属性来扩展 HTML. AngularJS 指令是扩展的 HTML 属性,带有前缀 ng-. 几个常用 指令: ng-app 指令 ...

  3. AngularJS 指令解析(二)

    AngularJS 指令解析(二) 第一篇我们讲过了作用域(scope)这块内容,现在我们进入正题,讲AngularJS的指令. 什么是指令? 这里我们引用官方的一句话: Custom directi ...

  4. AngularJS 指令实践指南(二)

    这个系列教程的第一部分给出了AngularJS指令的基本概述,在文章的最后我们介绍了如何隔离一个指令的scope.第二部分将承接上一篇继续介绍.首先,我们会看到在使用隔离scope的情况下,如何从指令 ...

  5. AngularJS(二)——常见指令以及下拉框实现

    前言 学完AngularJS,总体上感觉没什么新鲜的东西,但是又感觉每一步都很新鲜,因为没有见过,又因为学到的语法函数和JavaScript差不多,本篇主要介绍一些AngularJS的指令,常见指令和 ...

  6. AngularJS(二):ng-app指令、表达式

    本文也同步发表在我的公众号“我的天空” ng-app指令 AngularJS指令是扩展的HTML属性,所有指令均带有前缀“ng-”,我们学习的第一个指令便是ng-app,其定义了AngularJS管理 ...

  7. AngularJS指令

    1. AngularJS指令的特点: AngularJS通过被称为指令的新属性来扩展HTML,指令的前缀为ng-. AngularJS通过内置的指令来为应用添加功能. AngularJS允许你自定义指 ...

  8. AngularJs指令(一)

    AngularJs应用现在越来越流行了,谷歌都与微软合作支持AngularJS2.0,这是要逆天了,说明AngularJs将来大势所趋.最近想跳槽,又重新拾起了AngluarJs(之前由于缺少项目应用 ...

  9. 不用搭环境的10分钟AngularJS指令简易入门01(含例子)

    不用搭环境的10分钟AngularJS指令简易入门01(含例子) `#不用搭环境系列AngularJS教程01,前端新手也可以轻松入坑~阅读本文大概需要10分钟~` AngularJS的指令是一大特色 ...

随机推荐

  1. 禁用windows 10自动更新

    按Win键+R键调出运行,输入“gpedit.msc”点击“确定”,调出“本地组策略编辑器”.顺序依次展开计算机配置,管理模板 ,windows组件 ,windows更新 点击右边“配置自动更新”,选 ...

  2. Alljoyn 概述(2)

    AllJoyn 基本概念 • 总线(Bus) – 实现P2P通信的基础 – AllJoyn 的底层协议类似于D-Bus,相当于是跨设备分布式的 D-Bus • 总线附件(Bus Attachment) ...

  3. iOS 百度地图监听地图状态

    百度地图提供了地图状态的对象BMKMapStatus ///此类表示地图状态信息 @interface BMKMapStatus : NSObject { float _fLevel; // 缩放比例 ...

  4. iOS UICollectionview的详细介绍

    转载自:http://jinqianchina.github.io/2015/08/16/UICollectionview%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%A6%E8 ...

  5. JavaScript HTML DOM - 改变CSS

    JavaScript HTML DOM - 改变CSS HTML DOM 允许 JavaScript 改变 HTML 元素的样式. 改变 HTML 样式 如需改变 HTML 元素的样式,请使用这个语法 ...

  6. 微信小程序开发之入门篇(熟悉项目结构)

    微信小程序创建之后会生成一个项目模板,如下图所示(基本如此,但并不局限于此) 现在分别来说明一下每个文件及目录的意思 app.js 程序的入口文件,必须存在. app.js是小程序的脚本代码.我们可以 ...

  7. ie67 设置最小宽度最小高度

    1.最小宽度 min-width:1003px; _width:expression((document.documentElement.clientWidth||document.body.clie ...

  8. Linux下JDK环境变量配置

    JDK官方下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 我的下载路 ...

  9. java中的继承要点

    java的一大特性既是:继承. 1.因为有了一个子类继承了一个父类,才有了后面的多态. 2.类的继承,不要为了节省代码,为了继承而继承,把那个没有任何相关的类链接在一起,继承必须用在 is a,就是例 ...

  10. SGU 162.Pyramids

    时间限制:0.25s 空间限制:6M; 题意: 按照AB, AC, AD, BC, BD, CD.给出一个空间四面体的6条边长.求出它的体积. Solution: 欧拉四面体公式:           ...