详解angularjs中的隔离作用域理解以及绑定策略


Posted in Javascript onMay 31, 2017

我们首先看下面的例子:

<!doctype html> 
<html ng-app="MyModule"> 
 <head> 
  <meta charset="utf-8"> 
  <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" > 
 </head> 
 <body> 
  <hello></hello> 
  <hello></hello> 
  <hello></hello> 
  <hello></hello> 
 </body> 
 <script src="framework/angular-1.3.0.14/angular.js"></script> 
 <script src="IsolateScope.js"></script> 
</html>

我们在看看IsolateScope中的代码:

var myModule = angular.module("MyModule", []); 
myModule.directive("hello", function() { 
 return { 
  restrict: 'AE', 
  template: '<div><input type="text" ng-model="userName"/>{{userName}}</div>', 
  replace: true 
 } 
});

这时候当运行页面的时候发现只要有一个input中的输入变化了,这时候所有的nput的内容都会变化:

详解angularjs中的隔离作用域理解以及绑定策略

这样就会面临一个问题:我们的指令无法单独使用,于是就有了独立作用域的概念。

var myModule = angular.module("MyModule", []); 
myModule.directive("hello", function() { 
 return { 
  restrict: 'AE', 
  scope:{}, 
  template: '<div><input type="text" ng-model="userName"/>{{userName}}</div>', 
  replace: true 
 } 
});

通过把scope设置为{},那么每一个指令就具有自己独立的scope空间,于是就不会相互影响了。但是angularjs中最重要的概念是:绑定策略。其具有绑定策略如下:

详解angularjs中的隔离作用域理解以及绑定策略

第一步:我们看看原始的方式,也就是不使用上面的三种绑定方式

<!doctype html> 
<html ng-app="MyModule"> 
 <head> 
  <meta charset="utf-8"> 
  <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" > 
 </head> 
 <body> 
 <!--控制器MyCtrl下面有指令drink,同时指令drink还有自定义的属性flavor,其值为‘百威'--> 
  <div ng-controller="MyCtrl"> 
   <drink flavor="{{ctrlFlavor}}"></drink> 
  </div> 
 </body> 
 <script src="framework/angular-1.3.0.14/angular.js"></script> 
 <script src="ScopeAt.js"></script> 
</html>

看看ScopeAt中的内容:

var myModule = angular.module("MyModule", []); 
myModule.controller('MyCtrl', ['$scope', function($scope){ 
 $scope.ctrlFlavor="百威"; 
 //在控制器中$scope中设置了ctrlFlavor属性 
}]) 
//定义了drink指令 
myModule.directive("drink", function() { 
 return { 
  restrict:'AE', 
  template:"<div>{{flavor}}</div>" , 
   link:function(scope,element,attrs){ 
   scope.flavor=attrs.flavor; 
   //链接的时候把drink指令上的flavor属性放在scope中,然后在template中显示 
   } 
 } 
});

这时候的DOM结构如下:

详解angularjs中的隔离作用域理解以及绑定策略

但是,这种方式要通过attrs.flavor来获取这个指令的属性值,然后需要把这个属性值绑定到scope对象上,最后在template中才能通过{{}}这种形式获取到scope中的值!

第二步:我们使用上面的@来替换第一种方式,因为它每次都需要自己指定link函数:

var myModule = angular.module("MyModule", []); 
myModule.controller('MyCtrl', ['$scope', function($scope){ 
 $scope.ctrlFlavor="百威"; 
 //在控制器中$scope中设置了ctrlFlavor属性 
}]) 
//定义了drink指令 
myModule.directive("drink", function() { 
 return { 
  restrict:'AE', 
  scope:{ 
   flavor:'@' 
  }, 
  template:"<div>{{flavor}}</div>" 
 } 
});

这种方式就是把指令drink中的flavor属性值绑定到scope对象上,而且这是ng为我们自动绑定的。不过,@绑定绑定的是字符串,而不是对象!

第三步:我们来学习一下双向数据绑定

<!doctype html> 
<html ng-app="MyModule"> 
 <head> 
  <meta charset="utf-8"> 
  <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" > 
 </head> 
 <body> 
 <!--指定了控制器MyCtrl--> 
  <div ng-controller="MyCtrl"> 
   Ctrl: 
   <br> 
   <!--第一个输入框输入值绑定到ctrlFlavor,也就是控制器MyCtrl对应的ctrlFlavor值中--> 
   <input type="text" ng-model="ctrlFlavor"> 
   <br> 
   Directive: 
   <br> 
   <!--第二个输入框还是通过指令的方式来完成的--> 
   <drink flavor="ctrlFlavor"></drink> 
  </div> 
 </body> 
 <script src="framework/angular-1.3.0.14/angular.js"></script> 
 <script src="ScopeEqual.js"></script> 
</html>

我们再来看看控制器中内容

var myModule = angular.module("MyModule", []); 
//指定了控制器对象 
myModule.controller('MyCtrl', ['$scope', function($scope){ 
 $scope.ctrlFlavor="百威"; 
}]) 
//指定了指令 
myModule.directive("drink", function() { 
 return { 
  restrict:'AE', 
  scope:{ 
   flavor:'=' 
   //这里通过'='指定了drink指令的flavor和scope中的双向数据绑定! 
  }, 
  template:'<input type="text" ng-model="flavor"/>' 
 } 
});

这就是'='这种绑定方式。其实现了双向的数据绑定策略。我们看看最后的DOM结构是怎么样的:

详解angularjs中的隔离作用域理解以及绑定策略

其实双向数据绑定<drink flavor="ctrlFlavor"></drink>是很明显的,需要好好理解双向数据绑定(指令和控制器之间的双向数据绑定)

第四步:我们使用&绑定策略来完成对controller父级方法的调用:

<!doctype html> 
<html ng-app="MyModule"> 
 <head> 
  <meta charset="utf-8"> 
  <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" > 
 </head> 
 <body> 
  <div ng-controller="MyCtrl"> 
  <!--接下来是三个自定义的指令greeting指令--> 
   <greeting greet="sayHello(name)"></greeting> 
   <greeting greet="sayHello(name)"></greeting> 
   <greeting greet="sayHello(name)"></greeting> 
  </div> 
 </body> 
 <script src="framework/angular-1.3.0.14/angular.js"></script> 
 <script src="ScopeAnd.js"></script> 
</html>

其中定义了三个指令greeting,每一个指令都需要调用controller中的一个sayHello方法,(angularjs中如何实现控制器和指令之间交互指出了可以通过定义属性的方式使得控制器和指令之间进行交互,不过这里我们可以通过简单的&完成同样的功能)并且传入不同的参数name值:

var myModule = angular.module("MyModule", []); 
//为控制器指定了一个sayHello方法,同时为这个方法可以传入一个参数 
myModule.controller('MyCtrl', ['$scope', function($scope){ 
 $scope.sayHello=function(name){ 
  alert("Hello "+name); 
 } 
}]) 
myModule.directive("greeting", function() { 
 return { 
  restrict:'AE', 
  scope:{ 
   greet:'&'//传递一个来自父scope的函数用于稍后调用,获取greet参数,得到sayHello(name)函数 
  }, 
  //在template中我们在ng-click中指定一个参数,其指定方式为调用controller中greet方法,传入的参数name值为username 
  //也就是ng-model='userName'中指定的参数 
  template:'<input type="text" ng-model="userName" /><br/>'+ 
     '<button class="btn btn-default" ng-click="greet({name:userName})">Greeting</button><br/>' 
 } 
});

通过&就可以完成对父级作用方法的调用,而不是采用传统的通过为指令指定属性的方式完成控制器和指令之间的通行!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javscript对象原型的一些看法
Sep 19 Javascript
基于jquery的获取浏览器窗口大小的代码
Mar 28 Javascript
自己动手制作jquery插件之自动添加删除行的实现
Oct 13 Javascript
JavaScript Math.ceil() 函数使用介绍
Dec 11 Javascript
JQuery中serialize()用法实例分析
Feb 06 Javascript
教你如何使用firebug调试功能了解javascript闭包和this
Mar 04 Javascript
vue深入解析之render function code详解
Jul 18 Javascript
Node调用Java的示例代码
Sep 20 Javascript
Javascript中prototype与__proto__的关系详解
Mar 11 Javascript
Vue 中如何正确引入第三方模块的方法步骤
May 05 Javascript
JavaScript监听一个DOM元素大小变化
Apr 26 Javascript
微信小程序 获取手机号 JavaScript解密示例代码详解
May 14 Javascript
JS简单实现自定义右键菜单实例
May 31 #Javascript
页面间固定参数,通过cookie传值的实现方法
May 31 #Javascript
基于react框架使用的一些细节要点的思考
May 31 #Javascript
Angular 通过注入 $location 获取与修改当前页面URL的实例
May 31 #Javascript
使用原生js写ajax实例(推荐)
May 31 #Javascript
Javascript创建类和对象详解
May 31 #Javascript
Javascript继承机制详解
May 30 #Javascript
You might like
THINKPHP项目开发中的日志记录实例分析
2014/12/01 PHP
解析PHP之提取多维数组指定列的方法
2017/01/03 PHP
Yii Framework框架使用PHPExcel组件的方法示例
2019/07/24 PHP
php判断目录存在的简单方法
2019/09/26 PHP
PHP的new static和new self的区别与使用
2019/11/27 PHP
javascript工具库代码
2012/03/29 Javascript
捕获浏览器关闭、刷新事件不同情况下的处理方法
2013/06/02 Javascript
JQuery事件e参数的方法preventDefault()取消默认行为
2013/09/26 Javascript
在Ubuntu系统上安装Node.JS的教程
2015/10/15 Javascript
jquery插件EasyUI中form表单提交实例分享
2016/01/11 Javascript
Vue header组件开发详解
2018/01/26 Javascript
Angular利用trackBy提升性能的方法
2018/01/26 Javascript
JavaScript折半查找(二分查找)算法原理与实现方法示例
2018/08/06 Javascript
element-ui表格数据转换的示例代码
2018/08/24 Javascript
jQuery实现表格隔行换色
2018/09/01 jQuery
NodeJs 模仿SIP话机注册的方法
2019/06/21 NodeJs
js中switch语句的学习笔记
2020/03/25 Javascript
初学python数组的处理代码
2011/01/04 Python
Python内存管理方式和垃圾回收算法解析
2017/11/11 Python
python中实现k-means聚类算法详解
2017/11/11 Python
Python编程scoketServer实现多线程同步实例代码
2018/01/29 Python
python和opencv实现抠图
2018/07/18 Python
Python集合操作方法详解
2020/02/09 Python
pandas to_excel 添加颜色操作
2020/07/14 Python
Python 整行读取文本方法并去掉readlines换行\n操作
2020/09/03 Python
python 实现一个简单的线性回归案例
2020/12/17 Python
草莓巧克力:Shari’s Berries
2017/02/07 全球购物
北美最大的参茸药食商城:德成行
2020/12/06 全球购物
校友会欢迎辞
2014/01/13 职场文书
拾金不昧锦旗标语
2014/06/27 职场文书
小学社会实践活动总结
2014/07/03 职场文书
2014基层党员批评与自我批评范文
2014/09/24 职场文书
大学生上课迟到检讨书
2014/10/15 职场文书
2015年信贷员工作总结
2015/04/28 职场文书
张丽莉事迹观后感
2015/06/16 职场文书
Web前端:CSS最强总结 附详细代码
2021/03/31 HTML / CSS