详解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 相关文章推荐
Jquery中&quot;$(document).ready(function(){ })&quot;函数的使用详解
Dec 30 Javascript
使用jQuery异步加载 JavaScript脚本解决方案
Apr 20 Javascript
js操作数组函数实例小结
Dec 10 Javascript
浅谈JavaScript的全局变量与局部变量
Jun 10 Javascript
探究Vue.js 2.0新增的虚拟DOM
Oct 20 Javascript
jquery Easyui Datagrid实现批量操作(编辑,删除,添加)
Feb 20 Javascript
js获取地址栏参数的两种方法
Jun 27 Javascript
用react-redux实现react组件之间数据共享的方法
Jun 08 Javascript
vuejs中监听窗口关闭和窗口刷新事件的方法
Sep 21 Javascript
postman自定义函数实现 时间函数的思路详解
Apr 17 Javascript
小程序如何在不同设备上自适应生成海报的实现方法
Aug 20 Javascript
JavaScript组合设计模式--改进引入案例分析
May 23 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
php框架Phpbean说明
2008/01/10 PHP
PHP 设计模式系列之 specification规格模式
2016/01/10 PHP
CodeIgniter框架验证码类库文件与用法示例
2017/03/18 PHP
laravel 5.3 单用户登录简单实现方法
2019/10/14 PHP
JQuery Tips(3) 关于$()包装集内元素的改变
2009/12/14 Javascript
JS动态加载当前时间的方法
2015/02/09 Javascript
EasyUI实现第二层弹出框的方法
2015/03/01 Javascript
JavaScript中window.open用法实例详解
2015/04/15 Javascript
jQuery 1.9.1源码分析系列(十五)动画处理之缓动动画核心Tween
2015/12/03 Javascript
js实现文本框输入文字个数限制代码
2015/12/25 Javascript
JS控制弹出悬浮窗口(一览画面)的实例代码
2016/05/30 Javascript
JavaScript Ajax编程 应用篇
2016/07/02 Javascript
细数JavaScript 一个等号,两个等号,三个等号的区别
2016/10/09 Javascript
浅谈jQuery中Ajax事件beforesend及各参数含义
2016/12/03 Javascript
将鼠标焦点定位到文本框最后(代码分享)
2017/01/11 Javascript
jQuery控制元素隐藏和显示
2017/03/03 Javascript
以v-model与promise两种方式实现vue弹窗组件
2018/05/21 Javascript
vue select选择框数据变化监听方法
2018/08/24 Javascript
用POSTMAN发送JSON格式的POST请求示例
2018/09/04 Javascript
VSCode搭建React Native环境
2020/05/07 Javascript
[02:54]DOTA2英雄基础教程 撼地者
2014/01/14 DOTA
python统计cpu利用率的方法
2015/06/02 Python
Python从MP3文件获取id3的方法
2015/06/15 Python
Python3.5局部变量与全局变量作用域实例分析
2019/04/30 Python
pandas 数据结构之Series的使用方法
2019/06/21 Python
简单了解python的一些位运算技巧
2019/07/13 Python
pytorch制作自己的LMDB数据操作示例
2019/12/18 Python
python利用google翻译方法实例(翻译字幕文件)
2020/09/21 Python
基于Python中Remove函数的用法讨论
2020/12/11 Python
HTML5 在canvas中绘制矩形附效果图
2014/06/23 HTML / CSS
天美时手表加拿大官网:Timex加拿大
2016/09/01 全球购物
享受加州生活方式的时尚舒适:XCVI
2018/07/09 全球购物
春季防火方案
2014/05/10 职场文书
自强自立美德少年事迹材料
2014/08/16 职场文书
公司2015年终工作总结
2015/05/26 职场文书
2016年先进教师个人事迹材料
2016/02/26 职场文书