您的位置:首页 > Web前端 > AngularJS

新手学angularjs之指令

2016-07-07 17:44 369 查看
一个简单的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:‘
Hi Kobe!’

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",function(){
return {
restrict:"AE",
link:function(scope,element,attr){
//给元素绑定鼠标的事件
element.bind("mouseenter",function(){
scope.loadData();
}) ;
}
}
});


上面的范例加载的效果是:当鼠标经过的时候后台会打印出内容

怎么实现指令复用,在不同decontroller里面去使用指令?

将上面的范例做如下的修改

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 howtoload="loadData()">滑动加载!</loader>
</div>
<div data-ng-controller="MyCtrl2">
<loader howtoload="loadData2()">滑动加载!22222222</loader>
</div>
</body>
</html>


js代码

var myModule = angular.module('MyModule',[]);
myModule.controller('MyCtrl',['$scope',function($scope){
$scope.loadData=function(){
console.log("数据加载中!");
}
}]);
myModule.controller('MyCtrl2',['$scope',function($scope){
$scope.loadData2=function(){
console.log("数据加载中!22222222222");
}
}]);
myModule.directive("loader",function(){
return {
restrict:"AE",
link:function(scope,element,attr){
//给元素绑定鼠标的事件
element.bind("mouseenter",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',[]) ;
helloModule.directive('hello',function(){
return{
restrict:'AEMC',
template:'<div><input type="text" data-ng-model="userName" />{{userName}}</div>',
replace:true
}
}) ;


效果



如上,当我在第一个input输入框中输入“科比”的时候,其他几个input框业显示“科比”,这是有问题的,指令之间就没有办法相互独立使用了,那么解决办法

就是创建独立作用域?如下(只加一个配置就行了)

var helloModule = angular.module('Hello2',[]) ;
helloModule.directive('hello',function(){
return{
restrict:'AEMC',
scope:{},
template:'<div><input type="text" data-ng-model="userName" />{{userName}}</div>',
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",[]);
myModule.controller('MyCtrl',['$scope',function($scope){
$scope.ctrlFlavor="百威" ;
}]);
myModule.directive("drink",function(){
return {
restrict:"AE",
template:"<div>{{flavor}}</div>",
link:function(scope,element,attrs){
scope.flavor=attrs.flavor ;
}
}
});


用“@”

对js代码做如下修改:

var myModule = angular.module("MyModule",[]);
myModule.controller('MyCtrl',['$scope',function($scope){
$scope.ctrlFlavor="百威" ;
}]);
myModule.directive("drink",function(){
return {
restrict:"AE",
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",[]);
myModule.controller('MyCtrl',['$scope',function($scope){
$scope.ctrlFlavor="百威" ;
}]);
myModule.directive("drink",function(){
return {
restrict:"AE",
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",[]);
myModule.controller('MyCtrl',['$scope',function($scope){
$scope.sayHello = function(name){
alert("Hello"+name);
}
}]);
myModule.directive("greeting",function(){
return {
restrict:"AE",
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>"
}
});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  angularjs