接着上文说
其实在angularjs中。最复杂的一部分就是指令了(directive),指令的主要作用就是用来操纵和修改DOM,我们既可以使用angular提供的指令,也可以根据自己的需要来自定义指令。
angular提供的指令主要有ng-model ng-app ng-click等,但是更多的情况是我们需要根据自己的业务需求来自定义指令
举个例子,还记得上个博客中的那个service的例子嘛,好了,现在我想添加一个button,用来添加person
module.directive('addPersonButton',['Person',function(Person){
return {
restrict:'A',
link:function(scope,element,attrs){
element.bind('click',function(){
Person.addPerson({name:'hahh',age:20});
});
}
}
}]);
我们在我们的html中使用该指令:
<button add-person-button>Add Person </button>然后就可以随心所欲的添加了,以后每次要添加的时候我只要使用下这个指令就可以啦
好了,现在我们开始详细讲解:
你可以通过.directive函数来添加自定义的指令。
常见的自定义指令有两种:
一种是通过module直接定义如:
angular.module('starter')
.directive('myCustomer', function() {
return {
restrict: 'E',
templateUrl: 'directiveTest/my-customer.html'
};
})
})
第二种是借助于$compileProvider服务,通过$compileProvide.directive定义
var myApp = angular.module('myApp', [], ['$compileProvider',function ($compileProvider) {
$compileProvider.directive('customTags',function(){
return {
restrict:'ECAM',
template:'<div>custom-tags-html</div>',
replace:false
}
});
}])
要调用自定义指令,HTML元素上需要添加自定义指令名,使用驼峰法来命名一个指令,如上文的addPersonButton,使用时需要-来分割,于是变为add-person-button
现在来详细描述下指令中常见参数:
<script>
var app=angualr.module('myApp',[]);
app.directive('firstTest',function(){
return {
restrict:'ACEM'
template:'<h1>自定义指令</h1>'
replace:false,
// templateUrl :加载模板所要使用的URL
//replace :如果为true 则替换指令所在的元素,如果为false 或者不指定,则把当前指令追加到所在元素的内部
//restrict :下面将详细描述
//可以4种风格任意组合,如果忽略restrict,默认为A
// E : 风格为 元素 (作为标签名) 使用方式: <custom-tags>1212</custom-tags>
// C: 风格为 样式类 使用方式: <div class="custom-tags"> </div>
// A : 风格为 属性 使用方式: <div custom-tags> </div>
// M : 风格为 注释 <!--directive:first-test-->
// 注意:当有两个directive的时候 只能有一个template,否则会报错
};
});
</script>
我们挨个实验下:
元素名:
举例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body ng-app="myApp">
<first-test></first-test>
<script>
//添加我们上文写的directive
</script>
<p><strong>注意:</strong> 你必须设置 <b>restrict</b> 的值为 "C" 才能通过类名来调用指令。</p>
</body>
运行结果:
通常,directive默认的作用域是当前的父作用域,问题来了,我们在不同的controller中父作用域是不同的,我们想创建自己的作用域该如何做呢,或者说我想拥有自己的作用域当我需要用父作用域的变量的时候我再用应该怎么做呢,这时候就不得不说angular中的scope属性
scope的取值有两种:
false:默认使用的是父scope,
举个例子:
<!DOCTYPE html>
<html ng-app='MyApp'>
<meta charset="utf-8">
<head>
<script type="text/javascript" src='https://code.angularjs.org/1.5.10/angular.min.js'></script>
<script type="text/javascript">
function testC(){};
var app=angular.module('MyApp',[]);
app.controller('testC',testC).directive('myDirective', function() {
return {
restrict: 'E',
replace: true,
template: '<div><p>scope:<input type="text" ng-model="input"></p><p>结果:{{input}}</p></div>',
scope: false,
}
});
</script>
<body>
<body ng-controller="testC">
<p>父scope:<input type="text" ng-model="input"></p>
<!--自定义指令-->
<my-directive></my-directive>
</body>
</body>
</html>
结果如下:
可以看出来在directive中的input值完全是随着父scope的input值而变化,如果我们想单独创建自己的作用域,只需将scope这个属性定义为{}即可
<!DOCTYPE html>
<html ng-app='MyApp'>
<meta charset="utf-8">
<head>
<script type="text/javascript" src='https://code.angularjs.org/1.5.10/angular.min.js'></script>
<script type="text/javascript">
function testC(){};
var app=angular.module('MyApp',[]);
app.controller('testC',testC).directive('myDirective', function() {
return {
restrict: 'E',
replace: true,
template: '<div><p>scope<input type="text" ng-model="input"></p><p>result {{input}}</p></div>',
scope: {},
}
});
</script>
<body>
<body ng-controller="testC">
<p>father scope<input type="text" ng-model="input"></p>
<my-directive></my-directive>
</body>
</body>
</html>
3.现在我们创建独立的scope,但是我们希望能和父scope通信,即需要让子scope跟父scope中的变量进行绑定,常用的绑定策略有3种
- @单向绑定,外部scope能够影响内部的scope,但是内部的scope不能影响外部的scope
- =:双向绑定,外部scope和内部的scope的model能够相互影响,相互改变
- &:把内部scope的函数的返回值和外部scope的任何属性绑定起来
<!DOCTYPE html>
<html ng-app='MyApp'>
<meta charset="utf-8">
<head>
<script type="text/javascript" src='https://code.angularjs.org/1.5.10/angular.min.js'></script>
<script type="text/javascript">
function testC(){};
var app=angular.module('MyApp',[]);
app.controller('testC',testC).directive('myDirective', function() {
return {
restrict: 'E',
replace: true,
template: '<div><p>scope<input type="text" ng-model="selfinput"></p></div>',
scope: {
selfinput:'@'
},
}
});
</script>
<body>
<body ng-controller="testC">
<p>father scope<input type="text" ng-model="input"></p>
<my-directive selfinput={{input}}></my-directive>
</body>
</body>
</html>
<!DOCTYPE html>
<html ng-app='MyApp'>
<meta charset="utf-8">
<head>
<script type="text/javascript" src='https://code.angularjs.org/1.5.10/angular.min.js'></script>
<script type="text/javascript">
function testC(){};
var app=angular.module('MyApp',[]);
app.controller('testC',testC).directive('myDirective', function() {
return {
restrict: 'E',
replace: true,
template: '<div><p>scope<input type="text" ng-model="selfinput"></p></div>',
scope: {
selfinput:'='
},
}
});
</script>
<body>
<body ng-controller="testC">
<p>father scope<input type="text" ng-model="input"></p>
<!--注意这里,因为是双向绑定,所以这里不要“{{}}”这个符号-->
<my-directive selfinput=input></my-directive>
</body>
</body>
</html>
<!DOCTYPE html>
<html ng-app='MyApp'>
<meta charset="utf-8">
<head>
<script type="text/javascript" src='https://code.angularjs.org/1.5.10/angular.min.js'></script>
<script type="text/javascript">
var app=angular.module('MyApp',[]);
app.controller('testC',['$scope',
function($scope) {
$scope.test = function(){alert()};
}
]).directive('myDirective', function() {
return {
restrict: 'E',
replace: true,
template: '<div><button ng-click=clickme()>click me please</button></div>',
scope: {
clickme:'&'
},
}
});
</script>
<body>
<body ng-controller="testC">
<p>father scope<input type="text" ng-model="input"></p>
<my-directive clickme='test()'></my-directive>
</body>
</body>
</html>
结果当我们点击按钮的时候将自动弹出
<!DOCTYPE html>
<html ng-app='MyApp'>
<meta charset="utf-8">
<head>
<script type="text/javascript" src='https://code.angularjs.org/1.5.10/angular.min.js'></script>
<script type="text/javascript">
var app=angular.module('MyApp',[]);
app.controller('testC',['$scope',
function($scope) {
$scope.test = function(message){alert(message)};
}
]).directive('myDirective', function() {
return {
restrict: 'E',
replace: true,
template: "<div><input type='text' ng-model='answer'><button ng-click='clickme({message:answer})'>click me please</button></div>",
scope: {
clickme:'&'
},
}
});
</script>
<body>
<body ng-controller="testC">
<my-directive clickme='test(message)'></my-directive>
</body>
</body>
</html>
这样就完成了传递参数,ps:如果传递的是字符串的话,可以直接
return {
restrict: 'E',
replace: true,
template: "<div><input type='text' ng-model='answer'><button ng-click=clickme({message:‘goodmessage’})>click me please</button></div>",
scope: {
clickme:'&'
},
其他情况相同
欢迎大家批评指正