一个简单的hello指令:
例子:
HTML代码:
<!DOCTYPE html>
<html data-ng-app="HelloModule">
<head lang="en">
<Meta charset="UTF-8">
<title>Hello指令</title>
<script src="../js/angular.js"></script>
<script src="../js/Hello_Directive.js"></script>
</head>
<body>
<hello></hello>
<div hello></div>
<div class="hello"></div>
<!-- directive:hello -->
<div></div>
</body>
</html>
用到的js代码:
var helloModule = angular.module('HelloModule',[]) ;
helloModule.directive('hello',function(){
return{
restrict:'AEMC',template:'<div>Hi body!</div>',replace:true
}
}) ;
最后加载的效果:
应该会出现四个”Hi body!”
- 关于restrict
restrict:表示匹配模式,它一共有四个选择,分别是“A”、“E”、“M”、“C”
A:attribute(属性)
E:element(元素)
M:comment(注释)
C:class(css的样式类)
→ 体现匹配模式中的E
→体现匹配模式中的A
→体现匹配模式中的C
→体现匹配模式中的M
关于最后一种注释的写法需要注意directive前面和hello后面都是要空格的。
默认使用E,常用的是A,E
关于class一般是用来写css类的,这里写指令,搞在一起就有点混淆了。
关于template,templateUrl?
给定一个模板,相比templateUrl,template如果是遇到大量的html模板代码就会比较复杂,而如果用templateUrl只需要将一个定义好的完成的html模板的url路径设置给他就可以了。
范例:
template:‘
templateUrl:’hello.html’
template还有一个templateCache
$templateCache.put()将模板缓存起来,然后使用的时候在template的地方,在用get方法显示出来
var myModule = angular.module('MyModule',[]) ;
myModule.run(function($templateCache){
$templateCache.put("hello.html","<div>Hello Kobe.Bryant!!!!</div>") ;
});
myModule.directive("hello",function($templateCache){
return{
restrict:'AECM',template:$templateCache.get("hello.html"),repalce:true
}
});
关于repalce?
元素之间标签是可以嵌套的,用repalce就会将内部显示的内容替换掉.
HTML代码:
<!DOCTYPE html>
<html data-ng-app="MyModule">
<head lang="en">
<Meta charset="UTF-8">
<title></title>
<script src="../js/angular.js"></script>
<script src="../js/replace.js"></script>
</head>
<body>
<hello>
<div>这里是指令内部的内容!</div>
</hello>
</body>
</html>
对应js代码:
var myModule = angular.module('MyModule',[]);
myModule.directive("hello",function(){
return {
restrict:"AE",template:"<div>Hello Lebron James</div>",repalce:true
}
});
加载的效果是
只显示:Hello Lebron James
关于transclude?
对于repalce,如果要对将内部嵌套的标签的内容也显示出来,那么就要用到transclude。
var myModule = angular.module('MyModule',[])
myModule.directive('hello',function(){
return{
restrict:"AE",transclude:true,template:"<div>Hello Tracy.McGrady<div ng-transclude></div></div>"
}
});
加载的效果是:
Hello Tracy.McGrady
这里是指令内部的内容!
指令执行的大概的三个阶段
第一个阶段(加载)angularjs需要运行需要等待它加载完成,然后找到ng-app指令,然后就知道自己管理内容的权限。
第二个阶段(编译)遍历dom找到所有指令,然后根据指令去处理dom结构。
第三个阶段(链接)每条指令的link函数都会被定义去执行它。可以给dom元素绑定一些事件,也可以绑定作用域(双向绑定)。
指令和控制器之间怎么交互?
例子:
HTML代码:
<!DOCTYPE html>
<html data-ng-app="MyModule">
<head lang="en">
<Meta charset="UTF-8">
<title></title>
<script src="../js/angular.js"></script>
<script src="../js/HelloController.js"></script>
</head>
<body>
<div data-ng-controller="MyCtrl">
<loader>滑动加载!</loader>
</div>
</body>
</html>
js代码:
var myModule = angular.module('MyModule',[]);
myModule.controller('MyCtrl',['$scope',function($scope){
$scope.loadData=function(){
console.log("数据加载中!");
}
}]);
myModule.directive("loader",link:function(scope,element,attr){
//给元素绑定鼠标的事件
element.bind("mouseenter",function(){
scope.loadData();
}) ;
}
}
});
怎么实现指令复用,在不同decontroller里面去使用指令?
<!DOCTYPE html>
<html data-ng-app="MyModule">
<head lang="en">
<Meta charset="UTF-8">
<title></title>
<script src="../js/angular.js"></script>
<script src="../js/HelloController.js"></script>
</head>
<body>
<div data-ng-controller="MyCtrl">
<loader howtoload="loadData()">滑动加载!</loader>
</div>
<div data-ng-controller="MyCtrl2">
<loader howtoload="loadData2()">滑动加载!22222222</loader>
</div>
</body>
</html>
js代码
var myModule = angular.module('MyModule',function($scope){
$scope.loadData=function(){
console.log("数据加载中!");
}
}]);
myModule.controller('MyCtrl2',function($scope){
$scope.loadData2=function(){
console.log("数据加载中!22222222222");
}
}]);
myModule.directive("loader",function(event){
// scope.loadData();
scope.$apply(attr.howtoload);
}) ;
}
}
});
当鼠标在上面移动的时候后台就会打印出对应的信息。
指令与指令之间的交互?
通过内部的controller提供的方法。
关于独立作用域?
例子:
HTML代码:
<!DOCTYPE html>
<html data-ng-app="Hello2">
<head lang="en">
<Meta charset="UTF-8">
<title>Hello指令</title>
<script src="../js/angular.js"></script>
<script src="../js/Hello2.js"></script>
</head>
<body>
<hello></hello>
<hello></hello>
<hello></hello>
<hello></hello>
</body>
</html>
js代码:
var helloModule = angular.module('Hello2',template:'<div><input type="text" data-ng-model="userName" />{{userName}}</div>',replace:true
}
}) ;
效果
如上,当我在第一个input输入框中输入“科比”的时候,其他几个input框业显示“科比”,这是有问题的,指令之间就没有办法相互独立使用了,那么解决办法
就是创建独立作用域?如下(只加一个配置就行了)
var helloModule = angular.module('Hello2',scope:{},replace:true
}
}) ;
关于独立scope的绑定?
@ :把当前属性作为字符串传递,你还可以绑定来自外层scope的值。
= :与父scope中的属性进行双向绑定。
& :传递一个来自父scope的函数,稍后调用。(调用父层作用域上的函数)
@绑定(传递字符串)
首先举一个不用@绑定的例子:
HTML代码:
<!DOCTYPE html> <html data-ng-app="MyModule"> <head lang="en"> <Meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="../css/bootstrap.css" /> <script src="../js/angular.js"></script> <script src="../js/HelloScope1.js"></script> </head> <body> <div data-ng-controller="MyCtrl" > <drink flavor="{{ctrlFlavor}}"></drink> </div> </body> </html>
js代码
var myModule = angular.module("MyModule",function($scope){
$scope.ctrlFlavor="百威" ;
}]);
myModule.directive("drink",template:"<div>{{flavor}}</div>",attrs){
scope.flavor=attrs.flavor ;
}
}
});
var myModule = angular.module("MyModule",scope:{
flavor:"@"
},template:"<div>{{flavor}}</div>"
}
});
@绑定传递时字符串。
“=”绑定(进行双向绑定的)
HTML代码:
<!DOCTYPE html>
<html data-ng-app="MyModule">
<head lang="en">
<Meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="../css/bootstrap.css" />
<script src="../js/angular.js"></script>
<script src="../js/HelloScope2.js"></script>
</head>
<body>
<div data-ng-controller="MyCtrl" >
控制器里的flavor:
<br>
<input type="text" data-ng-model="ctrlFlavor" />
<br>
指令里的flavor:
<br>
<drink flavor="ctrlFlavor"></drink>
</div>
</body>
</html>
js代码:
var myModule = angular.module("MyModule",scope:{
flavor:"="
},template:"<input type='text' data-ng-model='flavor' />"
}
});
最终实现的效果是:修改控制器里的flavor的内容的时候指令里的flavor的内容也跟着修改了。达到了双向绑定的效果。
&绑定(用来传递一个函数的,用来调用父层作用域上的函数)
例子:
HTML代码:
<!DOCTYPE html>
<html data-ng-app="MyModule">
<head lang="en">
<Meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="../css/bootstrap.css" />
<script src="../js/angular.js"></script>
<script src="../js/HelloScope3.js"></script>
</head>
<body>
<div data-ng-controller="MyCtrl">
<greeting greet="sayHello(name)"></greeting>
<greeting greet="sayHello(name)"></greeting>
<greeting greet="sayHello(name)"></greeting>
</div>
</body>
</html>
js代码:
var myModule = angular.module("MyModule",function($scope){
$scope.sayHello = function(name){
alert("Hello"+name);
}
}]);
myModule.directive("greeting",scope:{
greet:"&"
},// 这里ng-click中的greet()方法中传递了一个对象,这个对象有一个name属性,这里用“:”把这个userName的值指给它
template:"<input type='text' data-ng-model='userName' /><br>" +
"<button class='btn btn-default' data-ng-click='greet({name:userName})' >Greet</button><br>"
}
});