前言
Angular 把后端mvc思想作用于前端设计,利用双向数据绑定使得开发更加得心应手,今天想把自己对Angular的绑定策略心得给大家分享一下,顺便也是为了巩固自己的知识
directive简介
在angular中,指令固然好用,但是内置的指令显然不能满足我们的需求,于是angular允许我们自己创建自定义的指令。
下面代码我们来创建一个自定义指令
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>blog</title>
</head>
<body>
<script src="./lib/angular.min.js" type="text/javascript"></script>
<script type="text/javascript">
angular.module("myApp",[])
//custom directive
.directive("hello",() => {
return {
restrict:"ECMA",
template:"<div></div>",
replace:true
};
});
.controller('myController', ['$scope', $scope => {
//controller
}]);
</script>
</body>
</html>
这样便创建了一个自定义指令,directive接受两个参数,第一个参数为该自定义指令的名称,第二个参数为类似于工厂的一个函数对象。
在这个函数对象里,我们要返回一个json对象,json里面的属性为该directive的配置项。
1.restrict
restrict表示需要怎样去引用这个指令,值为ECMA,分别对应与 Element,Class,Comment,Attribute,我们经常仅仅使用AE,因此我们引用的时候用元素和属性来引用就行了。
例如:
<hello></hello>
或者
<div hello></div>
2.template
该属性为该自定义指令指定一个模板进行渲染,我这里直接写为一个div,因此,当该自定义指令被angular解析的时候,实际是在dom树中渲染为:
<hello>
<div></div>
</hello>
但是当该模板的代码比较冗长的时候,我们可以选择使用templateUrl这个属性来进行渲染,比如我们在当前目录下有一个world.html这个文件,于是我们可以选择这样来写 :
//...some code
templateUrl:"./world.html"
//...some code
3.replace
这个属性就比较好理解了,replace字面意思就是替换,在上面模板渲染中,渲染出来的最终结果是 :
<hello>
<div></div>
</hello>
而如果我们把replace设置为true
这样渲染出阿里的最终结果应该为 :
<div></div>
闲扯了这么多,接下来进入正题,什么是@绑定
首先我们必须知晓,在自定义directive 中,还有一个属性叫做scope,比如我们来创建四个input输入框
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>blog</title>
</head>
<body>
<hello></hello>
<hello></hello>
<hello></hello>
<hello></hello>
<script src="./lib/angular.min.js" type="text/javascript"></script>
<script type="text/javascript">
angular.module("myApp",[])
//custom directive
.directive("hello",() => {
return {
restrict:"ECMA",
template:"<input type='text' ng-model='data' />",
replace:true
};
})
.controller('myController', ['$scope', $scope => {
//controller
}]);
</script>
</body>
</html>
结果如图所示 :
我们可以发现四个input的值都会同时改变,这是因为这四个input都被绑定在了同一个数据模型上。
然而,这并不是我们想要的结果不是吗。下面我改一下代码。
在return的json对象里加一个属性为scope
return {
//some code
socpe:{}
//some code
}
这样,我们为每个自定义的input创建了独立的作用域,现在每个Input的值虽然都是拥有相同名字的数据模型data,但是每个data都在它们所属的独立的作用域当中,因此,它们是互不影响的。
结果如下图所示 :
那么这样的话问题就来了,如果它创建了一个独立的作用域,那么就是说它与世隔绝了,这样我们的template就会处于一个‘无继承’状态,这样显然是不行的,于是,angular为我们提供了三种绑定策略(废话了那么多,终于进入主题了)。
Angular中的@绑定策略
使用@绑定,我们只需在scope 属性所指向的json对象里这样写就行了 :
return {
restrict:"ECMA",
template:"<input type='text' ng-model='data' />",
replace:true,
scope:{
text:"@"
}
}
上面的 text 表示为当前作用域中的一个属性。@表示绑定到父作用域的属性上。
下面我给大家一个完整的例子
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>blog</title>
</head>
<body>
<div ng-controller="myController">
<hello text="{{temp}}"></hello>
</div>
<script src="./lib/angular.min.js" type="text/javascript"></script>
<script type="text/javascript">
angular.module("myApp",[])
//custom directive
.directive("hello",() => {
return {
restrict:"ECMA",
template:"<div></div>",
replace:true,
scope:{
text:"@"
},
controller:$scope => {
//打印绑定的数据
console.log($scope.text);
}
};
})
.controller('myController', ['$scope', $scope => {
//controller
//父作用域
$scope.temp = "hello world";
}]);
</script>
</body>
</html>
当前myController创建的scope 即为父 scope ,而自定义的directive为子scope,我们用@绑定到text属性,因此,我们可以在控制台看到打印的结果
//console print
hello world
现在,@只可以绑定同名属性,比如
text:“@”
就只能绑定名为text的属性的值,然而,你还可以绑定其他名字的属性的值,比如我们要绑定一个名为world的属性的值
text:"@world"
我们只需这样写也是能获取到的。
Angular的 = 绑定策略
=是双向绑定,其用法跟@差不多,有个区别就是 = 不利于用来绑定字符串,比如,我们不改动上面的代码,我们直接把 @换成 =
结果在控制台里报出了一个错误
=通常用来绑定数据模型,因为用法跟@差不多,我这里就不再去很细的描述了,大家有问题可以在评论区回复我。
Angular的 & 绑定策略
&主要用来绑定父作用域上的函数,作为稍后调用。
比如我们在父作用域上定义了这么一个方法
.controller('myController', ['$scope', $scope => {
//controller
//父作用域
$scope.temp = "hello world";
//父作用域的方法
$scope.sayHello = () => {
alert("hello");
}
}]);
这个方法没什么好说的,它的主要作用就是调用浏览器内置的对话框弹出一个hello
现在我们在子作用域上进行绑定
html部分代码
<div ng-controller="myController">
<hello metho="sayHello()" text="{{temp}}"></hello>
</div>
js部分代码
.directive("hello",() => {
return {
restrict:"ECMA",
template:"<div></div>",
replace:true,
scope:{
text:"&metho"
},
controller:$scope => {
$scope.text();
}
};
})
我们在controller里直接调用了$scope的text方法,这个text又是绑定到父作用域上的sayHello方法,因此,我们在程序运行时可以看到这样的结果
以上就是Angular的绑定策略,如果此博文有什么错误请各位提出,我会及时改正
下面附上我的github地址,共勉
https://github.com/HaoDaWang