AngularJS1.X学习笔记10-自定义指令(下)
继续继续,学完这个部分就去吃饭。引用自由男人的话作为本文的开始:“默认情况下,链接函数被传入了控制器的作用域,而该控制器管理着的视图包含了指令所应用到的元素”。果然像是绕口令,还是看看你的例子比较好。
一、在一个控制器中应用同一指令
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>scope1</title> </head> <body ng-controller="directiveCtrul"> <get-data></get-data> <get-data></get-data> <script type="text/javascript" src="../node_modules/angular/angular.min.js"></script> <script type="text/javascript"> angular.module('myApp',[]) .controller('directiveCtrul',function($scope){ }) .directive("getData",function(){ return { template:"<div><input type='text' ng-model='name'/></div>" } }) </script> </body> </html>
这里给到自由男人的图解
可以发现,这两个directive是共用一个作用域的,所以说那两个文本框会保持同步状态。
二、我要的是做我自己
怎样才能是一个指令多次使用不相互影响呢?第一个想法是将他们放到不同的控制器,但是如果你就是想将它放到一个控制器中呢?scope:true就ok了
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>scope2</title> </head> <body ng-controller="directiveCtrul"> <get-data></get-data> <get-data></get-data> <script type="text/javascript" src="../node_modules/angular/angular.min.js"></script> <script type="text/javascript"> angular.module('myApp',[]) .controller('directiveCtrul',function($scope){ }) .directive("getData",function(){ return { template:"<div><input type='text' ng-model='name'/></div>", scope:true } }) </script> </body> </html>
这里还是用自由男人的例子来详细说明一下:
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>scope2</title> </head> <body ng-controller="directiveCtrul"> <get-data></get-data> <get-data></get-data> <script type="text/javascript" src="../node_modules/angular/angular.min.js"></script> <script type="text/javascript"> angular.module('myApp',[]) .controller('directiveCtrul',function($scope){ $scope.data = {name:"Adam"}; $scope.city = "London" }) .directive("getData",function(){ return { template:"<div>name:<input type='text' ng-model='data.name'/></div>"+ "<div>city:<input type='text' ng-model='city'/></div>"+ "<div>country:<input type='text' ng-model='country'/></div>", scope:true } }) </script> </body> </html>
这里给个比较复杂的图。
这里存在三种情况:(1)定义在一个对象上(data.name):被指令共享
` (2)直接定义在scope上(city):被指令共享,但是当用ng-model后会重建一个
(3)没有定义,动态创建(country):修改是创建,各个指令的没关系
三、拥抱自由
将scope置为true已经很自由了,但是,还是有一些属性会被指令共享,有没有一种方法让指令彻底解放呢?有的。
directive("getData",function(){ return { template:"<div>name:<input type='text' ng-model='data.name'/></div>"+ "<div>city:<input type='text' ng-model='city'/></div>"+ "<div>country:<input type='text' ng-model='country'/></div>", scope:{} } })
这下我们的指令完全解放了。看看自由男人给的图
四、我不想要太自由
有些时候我们并不希望太过自由,我们希望有那么一个人去叮嘱你,也希望有那么一个人可以倾诉。彻底的自由可能会让人手足无措。感谢Angular,这一切他都为我们实现了。
(1)找一个可以叮嘱的人
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>scope4</title> </head> <body ng-controller="directiveCtrul"> <input type="text" name="" ng-model="data.name"> <div get-data nameprop="{{data.name}}"></div> <script type="text/javascript" src="../node_modules/angular/angular.min.js"></script> <script type="text/javascript"> angular.module('myApp',[]) .controller('directiveCtrul',function($scope){ $scope.data = {name:"Adam"}; $scope.city = "London" }) .directive("getData",function(){ return { template:"<div>{{local}}</div>", scope:{local:"@nameprop"} } }) </script> </body> </html>
按理将,我创建了一个隔离作用域,他应该是控制器的数据没啥关系的,但是呢,我们让它有关系了,控制器的数据会单向留到指令中,指令的数据却不会到控制器中。为了证明指令的数据不会影响控制器的数据,我想改造一下上面的例子。
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>scope4</title> </head> <body ng-controller="directiveCtrul"> <div>我是控制器中的:<input type="text" name="" ng-model="data.name"></div> <div get-data nameprop="{{data.name}}"></div> <script type="text/javascript" src="../node_modules/angular/angular.min.js"></script> <script type="text/javascript"> angular.module('myApp',[]) .controller('directiveCtrul',function($scope){ $scope.data = {name:"Adam"}; $scope.city = "London" }) .directive("getData",function(){ return { template:"<div>指令中:{{local}}</div>"+ "我是指令中的:<input type='text' ng-model='data.name'> ", scope:{local:"@nameprop"} } }) </script> </body> </html>
我们发现在我是指令中的那个文本框输入不会影响我是控制器中的数据。这是一种单向数据流,可以从控制器留到指令,反之则不能。
(2)找一个既可以倾诉又可以叮嘱你的人
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>scope4</title> </head> <body ng-controller="directiveCtrul"> <div>控制器:{{data.name}}</div> <div>我是控制器中的:<input type="text" name="" ng-model="data.name"></div> <div get-data nameprop="data.name"></div> <script type="text/javascript" src="../node_modules/angular/angular.min.js"></script> <script type="text/javascript"> angular.module('myApp',[]) .controller('directiveCtrul',function($scope){ $scope.data = {name:"Adam"}; $scope.city = "London" }) .directive("getData",function(){ return { template:"<div>指令:{{local}}</div>"+ "我是指令中的:<input type='text' ng-model='local'> ", scope:{local:"=nameprop"} } }) </script> </body> </html>
这里创建了一个控制器和指令之间的双向数据流,控制器中的变化可以影响指令,指令中的变化也可以影响控制器。
(3)取得控制器中的函数
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>scope1</title> </head> <body ng-controller="directiveCtrul"> <get-data show="show()"></get-data> <script type="text/javascript" src="../node_modules/angular/angular.min.js"></script> <script type="text/javascript"> angular.module('myApp',[]) .controller('directiveCtrul',function($scope){ $scope.show = function(){ alert("hello"); } }) .directive("getData",function(){ return { template:"<button ng-click=show()>我是指令中的按钮</button>", scope:{ show:"&show" } } }) </script> </body> </html>
这个例子里,我们的指令是没有一个show方法的,但是它从控制器得到了这个方法,所以可以在指令中使用了。
或许你会问一个问题,为什么没有从指令到控制器的单向数据流呢?我也不知道哦。
四、总结一下
本文主要讲解了控制器作用域和指令作用域的关系。我们从控制器与指令作用域完全一样,到指令拥有自己的作用域,到指令作用域与控制器作用域完全分离,再到隔离作用域与控制器作用域的通信,比较清楚的理清了控制器作用域和指令作用域的复杂的情感纠葛。