前面通过视频学习了解了指令的概念,这里学习一下指令中的作用域的相关内容。

通过独立作用域的不同绑定,可以实现更具适应性的自定义标签。借由不同的绑定规则绑定属性,从而定义出符合更多应用场景的标签。

本篇将会总结下面的内容:

  1 为何需要独立作用域

  2 如何实现独立作用域

  3 作用域的数据绑定

之前有一些错误,是由于replace拼写错误导致的。

拼写正确后,网友发现报错,无法正常工作。这是因为模板中存在单标签<br>,导致模板无法正确解析~

再次感谢博友们提出的错误!

独立作用域的作用

  为了便于理解,先看一下下面这个例子:

  1. <!doctype html>
  2. <html ng-app="myApp">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
  6. </head>
  7. <body>
  8.  
  9. <div ng-controller="MainController">
  10. <xingoo></xingoo>
  11. <xingoo></xingoo>
  12. <xingoo></xingoo>
  13. </div>
  14.  
  15. <script type="text/javascript">
  16. var myAppModule = angular.module("myApp",[]);
  17.  
  18. myAppModule
  19. .controller('MainController', function($scope){
  20.  
  21. })
  22. .directive("xingoo",function(){
  23. return {
  24. restrict:'AE',
  25. template:'<div><input type="text" ng-model="username"/>{{username}}</div><br>'
  26. };
  27. });
  28. </script>
  29. </body>
  30. </html>

  可以看到,在script中,创建了一个指令,该指令实现了一个自定义的标签。

  标签<xingoo></xingoo>的作用是 替换成 一个输入框和一个数据显示。

  这样就会出现下面的效果:

  分析:

  当我们自己创建某个指令时,这个指令肯定不可能只使用一次,是要重复多次使用的,有的在一个页面内或者一个控制器内需要使用多次。

  类似上面的这种场景,在任何一个输入框内改变数据,都会导致其他的标签内的数据一同发生改变,这显然不是我们想要的。

  这个时候就需要独立作用域了。

如何实现独立作用域

  下面看看独立作用域的效果:

  1. <!doctype html>
  2. <html ng-app="myApp">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
  6. </head>
  7. <body>
  8.  
  9. <div ng-controller="MainController">
  10. <xingoo></xingoo>
  11. <xingoo></xingoo>
  12. <xingoo></xingoo>
  13. </div>
  14.  
  15. <script type="text/javascript">
  16. var myAppModule = angular.module("myApp",[]);
  17.  
  18. myAppModule
  19. .controller('MainController', function($scope){
  20.  
  21. })
  22. .directive("xingoo",function(){
  23. return {
  24. restrict:'AE',
  25. scope:{},//scope=true,
  26. template:'<div><input type="text" ng-model="username"/>{{username}}</div><br>'
  27. };
  28. });
  29. </script>
  30. </body>
  31. </html>

  只需要在定义指令时,添加scope:{}这个属性,就可以使标签拥有自己的作用域。

  仅仅是添加这一行代码而已,就实现了独立作用域。

  在进行输入时,每个模板内使用自己的数据,不会相互干扰。

作用域数据绑定  

  自定义标签或者进行扩展时,会有这样的需求场景,要在标签中添加一些属性,实现一些复杂功能。

  关于这些属性,独立作用域是如何的做的呢?看看下面的内容吧。

  举个例子:

  1. <xingoo say="name"></xingoo>
  2. <xingoo say="name()"></xingoo>

  假设传入的是上面这种,我们如何区分它传入的到底是变量呢?还是字符串呢?还是方法呢?

  因此AngularJS有了三种自定义的作用域绑定方式:

  1 基于字符串的绑定:使用@操作符,双引号内的内容当做字符串进行绑定。

  2 基于变量的绑定:使用=操作符,绑定的内容是个变量。

  3 基于方法的绑定:使用&操作符,绑定的内容时个方法。

基于字符串的绑定@:

  1. <!doctype html>
  2. <html ng-app="myApp">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
  6. </head>
  7. <body>
  8.  
  9. <div ng-controller="MainController">
  10. <xingoo say="test string"></xingoo>
  11. <xingoo say="{{str2}}"></xingoo>
  12. <xingoo say="test()"></xingoo>
  13. </div>
  14.  
  15. <script type="text/javascript">
  16. var myAppModule = angular.module("myApp",[]);
  17.  
  18. myAppModule
  19. .controller('MainController', function($scope){
  20. $scope.str1 = "hello";
  21. $scope.str2 = "world";
  22. $scope.str3 = "angular";
  23. })
  24. .directive("xingoo",function(){
  25. return {
  26. scope:{
  27. say:'@'
  28. },
  29. restrict:'AE',
  30. template:"<div>{{say}}</div>",
  31. replace:true
  32. };
  33. });
  34. </script>
  35. </body>
  36. </html>

  看一下代码,在body中使用了三次自定义的标签,每种标签的内部有一个say的属性,这个属性绑定了一个双引号的字符串。

  在指令的定义中,添加了scope:{say:'@'}这个键值对属性,也就是说,angular会识别say所绑定的东西是一个字符串。

  在模板中,使用表达式{{say}}输出say所表示的内容。

  可以看到,双引号内的内容都被当做了字符串。当然{{str2}}表达式会被解析成对应的内容,再当做字符串。

基于变量的绑定=:

  1. <!doctype html>
  2. <html ng-app="myApp">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
  6. </head>
  7. <body>
  8.  
  9. <div ng-controller="myAppCtrl">
  10. ctrl:<input type="text" ng-model="testname"><br>
  11. directive:<xingoo name="testname"></xingoo>
  12. </div>
  13.  
  14. <script type="text/javascript">
  15. var myAppModule = angular.module("myApp",[]);
  16.  
  17. myAppModule.controller("myAppCtrl",['$scope',function($scope){
  18. $scope.testname="my name is xingoo";
  19. }]);
  20.  
  21. myAppModule.directive("xingoo",function(){
  22. return {
  23. restrict:'AE',
  24. scope:{
  25. name:'='
  26. },
  27. template:'<input type="text" ng-model="name">',
  28. repalce:true
  29. }
  30. })
  31. </script>
  32. </body>
  33. </html>

  在上面的代码中,可以看到

  1 在控制器myAppCtrl对应的div中,定义了一个变量ng-model —— testname。

  2 testname对应的是输入框中输入的值。

  3 然后把这个变量当做一个参数传递给xingoo这个标签的name属性。

  4 在xingoo标签中,又把这个name绑定到模板中的一个输入框内。

  最终两个输入框的内容被连接起来,无论改变哪一个输入框内的值,testname与name都会发生改变。

  通过下面这张图可以看出来:

  在指令中通过scope指定say绑定规则是变量的绑定方式。

  最终通过xingoo标签内的属性依赖关系把 testname与name连接在一起:

  

基于方法的绑定&:

  上面展示了基于字符串和变量的绑定方法,下面看看基于方法的绑定:

  1. <!doctype html>
  2. <html ng-app="myApp">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
  6. </head>
  7. <body>
  8.  
  9. <div ng-controller="myAppCtrl">
  10. <xingoo say="sayHello(name)"></xingoo>
  11. <xingoo say="sayNo(name)"></xingoo>
  12. <xingoo say="sayYes(name)"></xingoo>
  13. </div>
  14.  
  15. <script type="text/javascript">
  16. var myAppModule = angular.module("myApp",[]);
  17.  
  18. myAppModule.controller("myAppCtrl",['$scope',function($scope){
  19. $scope.sayHello = function(name){
  20. console.log("hello !"+ name);
  21. };
  22. $scope.sayNo = function(name){
  23. console.log("no !"+ name);
  24. };
  25. $scope.sayYes = function(name){
  26. console.log("yes !"+ name);
  27. };
  28. }]);
  29.  
  30. myAppModule.directive("xingoo",function(){
  31. return {
  32. restrict:'AE',
  33. scope:{
  34. say:'&'
  35. },
  36. template:'<input type="text" ng-model="username"/><br>'+
  37. '<button ng-click="say({name:username})">click</button><br>',
  38. repalce:true
  39. }
  40. })
  41. </script>
  42. </body>
  43. </html>

  这段代码中scope中的绑定规则变成了&,也就是方法绑定。

  在body中,通过自定义标签传入了三个方法,分别是sayHello(name),sayNo(name),sayYes(name),这三个方法都需要一个name变量。

  在指令的定义中,模板替换成一个输入框,一个按钮:

  输入框:用于输入username,也就是三个方法需要的参数name。

  按钮:点击触发函数——通过绑定规则,绑定到相应的方法。

  

  也就是说

  通过say在scope中的定义,angular知道了say对应的是个方法;

  通过{name:username}的关联,知道了传入的是username。

  从而交给对应的方法执行。

  

  页面效果:

  参考

  [1] 大漠穷求,AngularJS实战:http://www.imooc.com/video/3085/0

【AngularJS】—— 12 独立作用域的更多相关文章

  1. angular的指令独立作用域(以及$watch的使用)

    在编写指令的时候,会有一个独立作用域的问题(scope),他默认的是 scope:false 不创建自己的作用域,直接使用的就是父级的作用域, 问题:容易出现全局的污染,是的指令的重复性使用回出现一些 ...

  2. AngularJs之Scope作用域

    前言: 上篇博文AngularJs之directive中说了Scope作用域是个大坑,所以拿出来作为重点总结! 什么是scope AngularJS 中,作用域是一个指向应用模型的对象,它是表达式的执 ...

  3. Angularjs里面跨作用域

    Angularjs里面跨作用域的实战!   好久没有来写博客了,最近一直在用Google的AngularJS,后面我自己简称AngularJS就叫AJ吧! 学习AngularJS一路也是深坑颇多啊-- ...

  4. AngularJs之四(作用域)

    一:angulaJs的作用域scope Scope(作用域) 是应用在 HTML (视图) 和 JavaScript (控制器)之间的纽带.scope 是一个 JavaScript 对象,带有属性和方 ...

  5. angularjs 控制器、作用域、广播详解

    一.控制器 首先列出几种我们平常使用控制器时的几种误区: 我们知道angualrJs中一个控制器时可以对应不同的视图模板的,但这种实现方式存在的问题是: 如果视图1和视图2根本没有任何逻辑关系,这样& ...

  6. AngularJS 中的作用域

    问题引入 使用 Angular 进行过一段时间的开发后,基本上都会遇到一个这样的坑: 123456789101112 <div ng-controller="TestCtrl" ...

  7. 转深入理解 AngularJS 的 Scope作用域

    文章转载英文:what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs 中文:http://www. ...

  8. Angularjs里面跨作用域的实战!

    好久没有来写博客了,最近一直在用Google的AngularJS,后面我自己简称AngularJS就叫AJ吧! 学习AngularJS一路也是深坑颇多啊--!就不多说了,不过还是建议大家有时间去学下下 ...

  9. AngularJs $rootScope.Scope 作用域操作

    这里讲的是一些scope的操作,如创建/注销/各种监听及scope间的通信等等. $rootScope.Scope 可以使用$injector通过$rootScope关键字检索的一个根作用域. 可以通 ...

随机推荐

  1. Failed to load JavaHL Library.

    以前使用的电脑是32位的,安装的svn可以正常使用,但是现在的电脑室64位的,安装好svn后,把项目提交到svn的过程中,总是弹出来一个错误的对话框: Failed to load JavaHL Li ...

  2. Python 之 lamda 函数

    1.例子 语法:lambda [args1,argus2....]:expression map(lambda x: x*x, [y for y in range(10)]) lambda:" ...

  3. LDA和PLSA

    看了<LDA数学八卦>和July的博客,里面涉及到好多公式推导...感觉好复杂,于是记录一些重点简洁的东西,忽略大批量铺垫,直接回答LDA和PLSA是区别: 在pLSA模型中,我们按照如下 ...

  4. Java开发视频网站大概需要多少钱?

    这个还真不好说,需要看你对视频网站有什么要求?你的数据库选择的是什么型号的?需要开发几个页面?服务器是需要高端的还是中低端的?还有你对完成时间有什么要求,这些细节也是决定价格的关键因素. 上面这些因素 ...

  5. C++混合编程之idlcpp教程Python篇(9)

    上一篇在这 C++混合编程之idlcpp教程Python篇(8) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相比,工程PythonTutorial7中除了四个文件PythonTu ...

  6. C++混合编程之idlcpp教程Python篇(8)

    上一篇在这 C++混合编程之idlcpp教程Python篇(7) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程PythonTutorial6中,同样加入了四个文件:Pyt ...

  7. Android性能优化典范第二季

      Google前几天刚发布了Android性能优化典范第2季的课程,一共20个短视频,包括的内容大致有:电量优化,网络优化,Wear上如何做优化,使用对象池来提高效率,LRU Cache,Bitma ...

  8. 使用Ivy管理项目中的依赖

    Ivy是什么 Ivy是一个跟踪管理项目直接以来关系的工具.Ivy具有良好的灵活性和可配置性,使其可以适应各种不同的依赖管理和构建过程要求:虽然Ivy作为依赖管理工具,其可以与Apache Ant进行紧 ...

  9. 用c#开发微信 系列汇总

    网上开发微信开发的教程很多,但c#相对较少.这里列出了我所有c#开发微信的文章,方便自己随时查阅.   一.基础知识 用c#开发微信(1)服务号的服务器配置和企业号的回调模式 - url接入 (源码下 ...

  10. bidi(双向文字)与RTL布局总结

    BIDI 双向文字就是一个字符串中包含了两种文字,既包含从左到右的文字又包含从右到左的文字. 大多数文字都是从左到右的书写习惯,比如拉丁文字(英文字母)和汉字,少数文字是从右到左的书写方式比如阿拉伯文 ...