详解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 相关文章推荐
javascript Discuz代码中的msn聊天小功能
May 25 Javascript
Javascript和Ajax中文乱码吐血版解决方案
Dec 21 Javascript
JavaScript EasyPager 分页函数
May 25 Javascript
javascript不同类型数据之间的运算的转换方法
Feb 13 Javascript
JS调试必备的5个debug技巧
Mar 07 Javascript
使用jquery animate创建平滑滚动效果(可以是到顶部、到底部或指定地方)
May 27 Javascript
javascript实现微信分享
Dec 23 Javascript
javascript模拟map输出与去除重复项的方法
Feb 09 Javascript
javascript基于prototype实现类似OOP继承的方法
Dec 16 Javascript
JS平滑无缝滚动效果的实现代码
May 06 Javascript
vue+echarts实现可拖动节点的折线图(支持拖动方向和上下限的设置)
Apr 12 Javascript
javascript开发实现贪吃蛇游戏
Jul 31 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
tp5 sum某个字段相加得到总数的例子
2019/10/18 PHP
a标签的css样式四个状态
2021/03/09 HTML / CSS
用js实现随机返回数组的一个元素
2007/08/13 Javascript
Input 特殊事件onpopertychange和oninput
2009/06/17 Javascript
Jquery submit()无法提交问题
2013/04/21 Javascript
js中的布尔运算符使用介绍
2013/11/20 Javascript
JavaScript操作HTML DOM节点的基础教程
2016/03/11 Javascript
jQuery代码实现表格中点击相应行变色功能
2016/05/09 Javascript
全面了解JavaScirpt 的垃圾(garbage collection)回收机制
2016/07/11 Javascript
JavaScript导航脚本判断当前导航
2016/07/12 Javascript
BootStrap学习笔记之nav导航栏和面包屑导航
2017/01/03 Javascript
jQuery插件版本冲突的处理方法分析
2017/01/16 Javascript
jQuery+CSS3实现点赞功能
2017/03/13 Javascript
javascript实现二叉树遍历的代码
2017/06/08 Javascript
weex里Vuex state使用storage持久化详解
2017/09/09 Javascript
jquery动态添加带有样式的HTML标签元素方法
2018/02/24 jQuery
vue的token刷新处理的方法
2018/07/17 Javascript
详解vue 在移动端体验上的优化解决方案
2019/05/20 Javascript
vue使用video.js进行视频播放功能
2019/07/18 Javascript
JavaScript switch语句使用方法简介
2019/12/30 Javascript
在js文件中引入(调用)另一个js文件的三种方法
2020/09/11 Javascript
使用相同的Apache实例来运行Django和Media文件
2015/07/22 Python
用Python实现命令行闹钟脚本实例
2016/09/05 Python
python提取xml里面的链接源码详解
2019/10/15 Python
TensorFLow 数学运算的示例代码
2020/04/21 Python
Python 中由 yield 实现异步操作
2020/05/04 Python
HTML5在线预览PDF的示例代码
2017/09/14 HTML / CSS
html5 canvas的绘制文本自动换行的示例代码
2018/09/17 HTML / CSS
西班牙电子产品购物网站:Electronicamente
2018/07/26 全球购物
优秀英语专业毕业生求职信
2013/11/23 职场文书
《画》教学反思
2014/04/14 职场文书
工作证明范本(2篇)
2014/09/14 职场文书
监察建议书
2015/02/04 职场文书
求职信范文怎么写
2015/03/19 职场文书
欠款起诉书范文
2015/05/19 职场文书
React如何创建组件
2021/06/27 Javascript