详解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 SocialHistory 检查访问者是否访问过某站点
Aug 02 Javascript
js 分栏效果实现代码
Aug 29 Javascript
js关闭父窗口时关闭子窗口
Apr 01 Javascript
Express作者TJ告别Node.js奔向Go
Jul 14 Javascript
探讨js字符串数组拼接的性能问题
Oct 11 Javascript
Underscore.js 1.3.3 中文注释翻译说明
Jun 25 Javascript
jquery中live()方法和bind()方法区别分析
Jun 23 Javascript
BootStrapValidator初使用教程详解
Feb 10 Javascript
bootstrap表单按回车会自动刷新页面的解决办法
Mar 08 Javascript
js中Array对象的常用遍历方法详解
Jan 17 Javascript
微信小程序开发(二):页面跳转并传参操作示例
Jun 01 Javascript
小程序选项卡以及swiper套用(跨页面)
Jun 19 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 object转数组示例
2014/01/15 PHP
YII实现分页的方法
2014/07/09 PHP
php实现读取超大文件的方法
2014/07/28 PHP
php页面,mysql数据库转utf-8乱码,utf-8编码问题总结
2015/08/27 PHP
PHP并发多进程处理利器Gearman使用介绍
2016/05/16 PHP
一个简单的js鼠标划过切换效果
2010/06/30 Javascript
javascript轻松实现当鼠标移开时已弹出子菜单自动消失
2013/12/29 Javascript
举例讲解jQuery中可见性过滤选择器的使用
2016/04/18 Javascript
基于bootstrap插件实现autocomplete自动完成表单
2016/05/07 Javascript
JS数组操作(数组增加、删除、翻转、转字符串、取索引、截取(切片)slice、剪接splice、数组合并)
2016/05/20 Javascript
AngularJS通过$sce输出html的方法
2016/09/22 Javascript
JS实现的驼峰式和连字符式转换功能分析
2016/12/21 Javascript
Vue2组件tree实现无限级树形菜单
2017/03/29 Javascript
vue-cli 3.x配置跨域代理的实现方法
2019/04/12 Javascript
微信小程序开发之获取用户手机号码(php接口解密)
2020/05/17 Javascript
Bootstrap FileInput实现图片上传功能
2021/01/28 Javascript
[51:07]VGJ.S vs Pain 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
Python读取一个目录下所有目录和文件的方法
2016/07/15 Python
基于Python实现对PDF文件的OCR识别
2016/08/05 Python
python爬虫中get和post方法介绍以及cookie作用
2018/02/08 Python
python使用matplotlib模块绘制多条折线图、散点图
2020/04/26 Python
详解Python3 pandas.merge用法
2019/09/05 Python
django前端页面下拉选择框默认值设置方式
2020/08/09 Python
Python结合百度语音识别实现实时翻译软件的实现
2021/01/18 Python
欧洲、亚洲、非洲和拉丁美洲的度假套餐:Great Value Vacations
2019/03/30 全球购物
Ajax请求总共有多少种Callback
2016/07/17 面试题
化学学院毕业生自荐信范文
2013/12/17 职场文书
2015年银行客户经理工作总结
2015/04/01 职场文书
2015年团队工作总结范文
2015/05/04 职场文书
重阳节简报
2015/07/20 职场文书
《观潮》教学反思
2016/02/17 职场文书
2019年入党思想汇报格式与要求
2019/06/25 职场文书
Windows10下安装MySQL8
2021/04/06 MySQL
使用HttpSessionListener监听器实战
2022/03/17 Java/Android
十大最强水系宝可梦,最美宝可梦排第三,榜首大家最熟悉
2022/03/18 日漫
Redis Lua脚本实现ip限流示例
2022/07/15 Redis