详解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 相关文章推荐
用脚本调用样式的几种方法
Dec 09 Javascript
基于Jquery的表格隔行换色,移动换色,点击换色插件
Dec 22 Javascript
纯js分页代码(简洁实用)
Nov 05 Javascript
js sort 二维数组排序的用法小结
Jan 24 Javascript
Jquery Ajax解析XML数据(同步及异步调用)简单实例
Feb 12 Javascript
JS简单实现城市二级联动选择插件的方法
Aug 19 Javascript
基于jquery实现简单的分页控件
Mar 17 Javascript
AngularJS压缩JS技巧分析
Nov 08 Javascript
微信小程序云开发使用方法新手初体验
May 16 Javascript
自定义javascript验证框架示例【附源码下载】
May 31 Javascript
vue数据更新UI不刷新显示的解决办法
Aug 06 Javascript
JS中锚点链接点击平滑滚动并自由调整到顶部位置
Feb 06 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分页显示制作详细讲解
2006/10/09 PHP
PHP正确解析UTF-8字符串技巧应用
2012/11/07 PHP
PHP中应该避免使用同名变量(拆分临时变量)
2015/04/03 PHP
YII视图整合kindeditor扩展的方法
2016/07/13 PHP
CakePHP框架Model函数定义方法示例
2017/08/04 PHP
PHP APP微信提现接口代码
2018/09/30 PHP
jQuery多项选项卡的实现思路附样式及代码
2014/06/03 Javascript
总结jQuery插件开发中的一些要点
2016/05/16 Javascript
JS获取鼠标选中的文字
2016/08/10 Javascript
JS只能输入正整数的简单实例
2016/10/07 Javascript
微信小程序 input输入框控件详解及实例(多种示例)
2016/12/14 Javascript
jQuery+ajax的资源回收处理机制分析
2017/01/07 Javascript
微信小程序 地图map详解及简单实例
2017/01/10 Javascript
angularjs下ng-repeat点击元素改变样式的实现方法
2018/09/12 Javascript
js前端面试之同步与异步问题详解
2019/04/03 Javascript
Vue实现浏览器打印功能的代码
2020/04/17 Javascript
es5 类与es6中class的区别小结
2020/11/09 Javascript
[11:42]2018DOTA2国际邀请赛寻真——OG卷土重来
2018/08/17 DOTA
解决python nohup linux 后台运行输出的问题
2018/05/11 Python
python 异或加密字符串的实例
2018/10/14 Python
Python深拷贝与浅拷贝用法实例分析
2019/05/05 Python
解决numpy矩阵相减出现的负值自动转正值的问题
2020/06/03 Python
最新pycharm安装教程
2020/11/18 Python
详解CSS3的图层阴影和文字阴影效果使用
2016/06/09 HTML / CSS
CSS3,线性渐变(linear-gradient)的使用总结
2017/01/09 HTML / CSS
CSS3 @media的基本用法总结
2019/09/10 HTML / CSS
解决HTML5中的audio在手机端和微信端的不能自动播放问题
2019/11/04 HTML / CSS
如何进行Linux分区优化
2013/02/12 面试题
大学本科毕业生的自我鉴定范文
2013/11/19 职场文书
数学专业推荐信范文
2013/11/21 职场文书
火锅店的活动方案
2014/08/15 职场文书
合作协议书模板
2014/10/10 职场文书
通知的格式范文
2015/04/27 职场文书
Python爬虫实战之爬取携程评论
2021/06/02 Python
Mongo服务重启异常问题的处理方法
2021/07/01 MongoDB
移除Selenium中window.navigator.webdriver值
2022/06/10 Python