码迷,mamicode.com
首页 > Web开发 > 详细

angularJS 指令二

时间:2016-07-21 23:26:05      阅读:292      评论:0      收藏:0      [点我收藏+]

标签:

指令详解
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 指令二

标签:

原文地址:http://www.cnblogs.com/lyy-2016/p/5693424.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!