共计 5531 个字符,预计需要花费 14 分钟才能阅读完成。
一、指令简介
指令:自定义HTML元素和属性。基于对HTML的理解,指令本质上就是angularJS扩展具有自定义功能的HTML元素的途径。
<my-video my-href="/god.mp4">mp4</my-video>
<video my-href="/god.mp4">mp4</video>
上面的第二种书写方式表示:指令可以和其他指令或者属性组合在一起使用,这种组合使用方式叫做合成。
指令的分类
1.内置指令如ng-app,ng-module等等。
2.自定义指令。先创建一个自定义标签(或者说不用自定义也行)
<my-directive></my-directive>
<script type="text/javascript">
angular.module('my-app', []).directive('myDirective', function() {
return {
restrict: 'E',
replace: true,
template: '<a href="http://www.baidu.com">click me</a>'
}
})
</script>
通过调用angularJS模块api中的directive()方法,传入一个字符串(表示指令的名字),和一个函数(返回一个对象)。其中对象中restrict是申明用什么方式来添加功能,主要有4个值为ECMA。分别表示元素,类,注释,属性。
- E:<my-directive></my-directive>
- C:<div class=’my-directive’></div>
- M:<!–directive:my-directive–>
- A:<div my-directive></div>
replace设置为true是表示将自定义标签从生成的DOM中完全移除掉,只留下有模板生成的连接。template是表示生成的模板。
3.表达式与指令
<div ng-controller='ParentCtrl'>
<p>we can access:{{ rootProenty }} and {{ parentProperty }}</p>
<div ng-controller='ChildCtrl'>
<p>we can access:{{ rootProenty }} and {{ parentProperty }} and {{ childProperty }}</p>
<p>{{ fullSentenceFormChild }}</p>
</div>
</div>
<script>
angular.module('my-app', [])
.run(function($rootScope) {
// 使用.run访问$rootScrope
$rootScope.rootProenty = "Root scope";
})
.controller('ParentCtrl', function($scope) {
//使用.controller访问'ng-controller'内部的属性
//在DOM忽略的$scope中,根据当前控制器进行推断
$scope.parentProperty = "Parent scope";
})
.controller('ChildCtrl', function($scope) {
$scope.childProperty = "Child scope";
//同在DOM中一样,我们可以通过当前的$scope直接访问原型中的任意属性
$scope.fullSentenceFormChild = "Same $scope: we can access:" +
$scope.rootProenty + " and " +
$scope.parentProperty + " and " +
$scope.childProperty
});
</script>
4.向指令中传递数据
<div my-directive my-url="http://www.baidu.com" my-link-text="Click me To baidu"> </div>
<script type="text/javascript">
angular.module('my-app', []).directive('myDirective', function() {
return {
restrict: 'A',
replace: true,
template: '<a href="{{ myUrl }}">{{ myLinkText }}</a>'
}
})
</script>
刷新页面之后,注意声明指令的部分已经被模板代替,但是连接的href属性还是空的,并且内容为空?
有好几种方法可以设置指令内部作用域中属性的值。最简单的方法就是使用由所属控制器提供的已经存在的作用域。当然angularJS也允许创建独立作用域(隔离作用域)或者新的子作用域来解决常见问题。
那么就要先说说,什么是绑定策略@。绑定策略告诉AngularJS将DOM中的some-propenty属性的复制给新作用域对象中的somePropenty属性:
<div my-directive some-attr="set @ binding"></div>
<script type="text/javascript">
angular.module('my-app', []).directive('myDirective', function() {
return {
restrict: 'A',
replace: true,
scope: {
someProenty: '@someAttr'
},
template: '<div>{{ someProenty }}</div>'
}
})
</script>
指令也可以有自己的控制器,这种情况下,我们可以自己设置其属性的值
<div my-directive some-attr="set @ binding"></div>
<script type="text/javascript">
angular.module('my-app', []).directive('myDirective', function() {
return {
restrict: 'A',
replace: true,
template: '<div>{{ someProenty }}</div>',
controller: function($scope) {
$scope.someProenty = "這是一個綁定策略"
}
}
})
</script>
回到刚才那个例子,我们可以用属性将数据从DOM中复制到指令的独立作用域中:
<div my-directive my-url="http://www.baidu.com" my-link-text="Click me To baidu"></div>
<script type="text/javascript">
angular.module('my-app', []).directive('myDirective', function() {
return {
restrict: 'A',
replace: true,
scope: {
myUrl: '@',//綁定策略
myLinkText: '@',//綁定策略
},
template: '<a href="{{ myUrl }}">{{ myLinkText }}</a>'
}
})
</script>
由于作用域中属性经常是私有的,因此可以指定我们希望的某个属性与那个DOM绑定:
<div my-directive my-url="http://www.baidu.com" some-attr="這是私有連接" my-link-text="Click me To baidu"></div>
<script type="text/javascript">
angular.module('my-app', []).directive('myDirective', function() {
return {
restrict: 'A',
replace: true,
scope: {
myUrl: '@',//綁定策略
myLinkText: '@someAttr',//綁定策略
},
template: '<a href="{{ myUrl }}">{{ myLinkText }}</a>'
}
})
</script>
5.双向数据绑定与向指令传递数据
在上面的例子中,还可以在DOM对应的作用域上运算表达式,并将表达式传递给指令,在指令内部最终被绑定在属性上:
<label>Their URL field:</label>
<input type="text" ng-model="theirUrl" autofocus="autofocus" autocomplete="on" placeholder="http://www.baidu.com"/>
<div my-directive some-attr="theirUrl" my-link-text="Click me To Link"></div>
<script type="text/javascript">
angular.module('my-app', [])
.directive('myDirective', function() {
return {
restrict: 'A',
replace: true,
scope: {
myUrl: '=someAttr', //經過了修改
myLinkText: '@'
},
template: '\
<div>\
<label>My URL field:</label>\
<input type="text" ng-model="myUrl"/>\
<a href="{{myUrl}}" target="_blank">{{myLinkText}}</a>\
</div>'
}
})
</script>
内置指令ng-model在它自身内部的独立作用域和DOM的作用域(由控制器提供)之间创建了一个双向数据绑定。ng-model=’theirUrl’和some-attr=”theirUrl”之间。在经过修改myUrl:’=someAttr’达到最终实现效果。