angularjs 实现原理中数据双向绑定是怎么实现的?原理是什么

AngulaJS 中$watch()的应用以及ng-model实现数据双向绑定
AngulaJS 中$watch()的应用以及ng-model实现数据双向绑定
[摘要:刚进一个新项目组,前端用的是AngularJs 的器械,刚最先不停很冲突那个器械,不外比来最先写面器械,发明实在照样蛮好用的,针对本日碰到的题目做一个总结。 题目是如许的 :一个]
& & & & 刚进一个新项目组,前端用的是AngularJs 的东西,刚开始一直很抵触这个东西,不过最近开始写点东西,发现其实还是蛮好用的,针对今天遇到的问题做一个总结。
问题是这样的 :一个页面上有两个单选按钮radio(name相同)A、B,然后有两个下拉框select :sA、sB,要求点A是,sA显示,sB隐藏; 点B时sB显示,sA隐藏.....(先说这个简单的例子)
解决方案:给两个radio加相同的 ng-model (如:
ng-model=&radioModel&),然后分别给两个下拉框加ng-model(sAm和sBm),和ng-show(sAs和sBs)(用来控制显示的)
注意:AngulaJS 中一个很牛的地方就是实现了数据的双向绑定,这里ng-model 就能实现,单选框ng-model 对应 value 属性的值;下拉框的ng-model则对应option 中的value属性值。这样js中就可以直接用其控制,如:
if($scope.radioModel == 'valA'){
$scope.sAs =
$scope.sBs =}
当然需要这样:
$scope.$watch(‘radioModel’,function(){
& & & & &if($scope.radioModel == 'valA'){//为radio的value值
$scope.sAs =&
$scope.sBs =
同理也可以对下拉框进行监控。。。。
===========================以下是分享网友的
在使用AngulaJS编写应用时,我们经常需要做的一件事情就是对模型中的变量进行监视,并对其发生的变化做出相应的回应。AngularJS为我们提供了一个非常方便的$watch方法,它可以帮助我们在每个scope中监视其中的变量。下面是一个非常简单的例子:
&html& &head&
&script src='./lib.angular.min.js'&&/script& &/head& &body ng-app='watch'&
&input ng-model='name' type='text'/&
&div&change count: {{count}}&/div&
angular.module('watch',[])
.run(['$rootScope',function($rootScope){
$rootScope.count = 0;
$rootScope.name = 'Alfred';
$rootScope.$watch('name',function(){
$rootScope.count++;
&/script& &/body& &/html&
上面的这段代码非常简单,它用$watch来对$rootScope中的name进行监视,并在它发生变化的时候将$rootScope中的count属性增加1。因此,每当我们对name进行一次修改时,下面显示的change count数字就会增加1。
在AngularJS内部,每当我们对ng-model绑定的name属性进行一次修改,AngularJS内部的$digest就会运行一次,并在运行结束之后检查我们使用$watch来监视的东西,如果和进行上一次$digest之前相比有了变化,则执行我们在其中绑定的处理函数。
然而,我们在实际运用中常常不只是对一个原始类型的属性进行监视,如果你还记得Javascript中的六种基本类型,你一定会记得原始类型(数字,字符串)和引用类型的区别。对于原始类型,如果我们使用了一个赋值操作,则这个原始类型变量会“真正的”被进行一次复制,然而对于引用类型,在进行赋值时,仅仅时将赋值的变量指向了这个引用类型。在AngularJS的$watch方法中,对两者的操作也有不同之处。原始类型,就像我们上面例子中提到的$rootScope,没有什么特别之处,然而如果要对一个引用类型,尤其是在实际运用中常见的对象数组进行监视时,情况就不一样了。我们来看下面的例子:
&html& &head&
&script src='./lib.angular.min.js'&&/script& &/head& &body ng-app='watch'&
&div hg-repeat='item in items'&
&input ng-model='item.a'/&&span&{{item.a}}&/span&
&div&change count: {{count}}&/div&
angular.module('watch',[])
.run(['$rootScope',function($rootScope){
$rootScope.count = 0;
$rootScope.items = [
{ &a&: 1 },
{ &a&: 2 },
{ &a&: 3 },
{ &a&: 4 }
$rootScope.$watch('items',function(){
$rootScope.count++;
&/script& &/body& &/html&
此时,如果我们对四个input中的a进行改变时,我们会发现,count的值依然是0。这是怎么回事?难道没有$watch失灵了吗?
正如我们前面所说的,$watch在对待原始类型和引用类型会有不同的处理方式,这就要首先说一说$watch函数的第三个参数。在前面的例子中,我们知道,$watch函数有接收两个参数,第一个参数是需要监视的对象,第二个参数是在监视对象发生变化时需要调用的函数,实际上$watch还有第三个参数,它在默认情况下是false。在默认情况下,即不显式指明第三个参数或者将其指明为false时,我们进行的监视叫做“引用监视”。引用监视的原词的“reference watch”,它的意思是只要监视的对象引用没有发生变化,就不算它发生了变化。具体来说,在上面的例子中,只要是items的引用没有发生变化,就算items中的一些属性发生了变化,$watch也会当做没有看见。那么在什么时候算是引用发生了变化呢?比如说将一个新的数组newItems赋值给items,此时$watch才会站出来说:“你变了!你再也不是以前我认识的那个和我一起看星星看月亮聊人生理想并且教会我什么叫做爱的人了!”
相反,如果我们将$watch的第三个变量设置为true,那么此时我们进行的监视叫做“全等监视”,原词是“equality watch”。此时,$watch就像是一个醋意十足的恋人,只要看他的对象有一点风吹草动,马上就跳出来,大喊大叫:“你冷酷你无情,你无理取闹。就算我冷酷,我无情,我无理取闹,也没有你冷酷你无情,你无理取闹!尔康。。。。。”。
因此,有同学就会问了,既然全等监视这么好,那么我们为什么不直接用全等监视呢?当然,任何事情都有好的坏的两个方面,全等监视固然是好,但是它在运行时需要先遍历整个监视对象,然后在每次$digest之前使用angular.copy()将整个对象深拷贝一遍然后在运行之后用angular.equal()将前后的对象进行对比,上面的例子中因为items比较简单,因此可能性能上不会有什么差别,但是到了实际生产时,我们要面对的数据千千万万,可能因为全等监视这一个设置就会消耗大量的资源,让应用停滞不前。因此这就需要我们在使用时进行权衡,究竟应该使用哪一种监视方式。
除了上面提到的两种方式之外,在angular 1.1.4版本之后,添加了一个$watchCollection()方法来针对数组(也就是集合)进行监视,它的性能介于全等监视和引用监视二者之间,即它并不会对数组中每一项的属性进行监视,但是可以对数组的项目的增减做出反应。比如还是上面的例子:
$rootScope.items = [
{ &a&: 1 },
{ &a&: 2 },
{ &a&: 3 },
{ &a&: 4 }
$rootScope.$watchCollection('items',function(){
$rootScope.count++;
如果改变了items[0]的a属性值,$watch并不会做出反应,但是如果我们在items上push或者pop了一个项目,$watch就会开始行动了。
关于AngularJS中$watch部分就讲这么多,还是那句话“最好的学习方式就是实践”。多coding,多犯错,一定能学好AngularJS。
感谢关注 Ithao123JS频道,是专门为互联网人打造的学习交流平台,全面满足互联网人工作与学习需求,更多互联网资讯尽在 IThao123!
Laravel是一套简洁、优雅的PHP Web开发框架(PHP Web Framework)。它可以让你从面条一样杂乱的代码中解脱出来;它可以帮你构建一个完美的网络APP,而且每行代码都可以简洁、富于表达力。
Hadoop是一个由Apache基金会所开发的分布式系统基础架构。
用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。
Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求,可以以流的形式访问(streaming access)文件系统中的数据。
Hadoop的框架最核心的设计就是:HDFS和MapReduce。HDFS为海量的数据提供了存储,则MapReduce为海量的数据提供了计算。
产品设计是互联网产品经理的核心能力,一个好的产品经理一定在产品设计方面有扎实的功底,本专题将从互联网产品设计的几个方面谈谈产品设计
随着国内互联网的发展,产品经理岗位需求大幅增加,在国内,从事产品工作的大部分岗位为产品经理,其实现实中,很多从事产品工作的岗位是不能称为产品经理,主要原因是对产品经理的职责不明确,那产品经理的职责有哪些,本专题将详细介绍产品经理的主要职责
IThao123周刊AngularJS数据双向绑定,如何实现数组从view到model的绑定?
网上有很多是从model到view的绑定,比如先在angular里声明一个数组array,然后用ng-repeat指令,生成到view里,接下来就可以通过控制这个array的值,实现model影响到view,但是我现在是页面上有一组元素,并不是通过ng-repeat指令生成的,我现在想把它们放到model数组里,该怎么实现呢?谢谢!
暂无任何回答
7094人关注
Copyright (C)
All Rights Reserved | 京ICP备 号-2双向数据绑定---AngularJS的基本原理学习 - 推酷
双向数据绑定---AngularJS的基本原理学习
Angular JS (Angular.JS) 是一组用来开发Web页面的框架、模板以及数据绑定和丰富UI组件。它支持整个开发进程,提供web应用的架构,无需进行手工DOM操作。 AngularJS很小,只有60K,兼容主流浏览器,与 jQuery 配合良好。双向数据绑定可能是AngularJS最酷最实用的特性,将MVC的原理展现地淋漓尽致.
AngularJS的工作原理是:HTML模板将会被浏览器解析到DOM中, DOM结构成为AngularJS编译器的输入。AngularJS将会遍历DOM模板, 来生成相应的NG指令,所有的指令都负责针对view(即HTML中的ng-model)来设置数据绑定。因此, NG框架是在DOM加载完成之后, 才开始起作用的.&
&body ng-app=&ngApp&&
&div ng-controller=&ngCtl&&
&label ng-model=&myLabel&&&/label&
&input type=&text& ng-model=&myInput& /&
&button ng-model=&myButton& ng-click=&btnClicked&&&/button&
// angular app
var app = angular.module(&ngApp&, [], function(){
console.log(&ng-app : ngApp&);
// angular controller
app.controller(&ngCtl&, [ '$scope', function($scope){
console.log(&ng-controller : ngCtl&);
$scope.myLabel = &text for label&;
$scope.myInput = &text for input&;
$scope.btnClicked = function() {
console.log(&Label is & + $scope.myLabel);
如上,我们在html中先定义一个angular的app,指定一个angular的controller,则该controller会对应于一个作用域(可以用$scope前缀来指定作用域中的属性和方法等). 则在该ngCtl的作用域内的HTML标签, 其值或者操作都可以通过$scope的方式跟js中的属性和方法进行绑定.&
这样, 就实现了NG的双向数据绑定: 即HTML中呈现的view与AngularJS中的数据是一致的. 修改其一, 则对应的另一端也会相应地发生变化.
这样的方式,使用起来真的非常方便. 我们仅关心HTML标签的样式, 及其对应在js中angular controller作用域下绑定的属性和方法. 仅此而已, 将众多复杂的DOM操作全都省略掉了.
这样的思想,其实跟jQuery的DOM查询和操作是完全不一样的, 因此也有很多人建议用AngularJS的时候,不要混合使用jQuery. 当然, 二者各有优劣, 使用哪个就要看自己的选择了.
NG中的app相当于一个模块module, 在每个app中可以定义多个controller, 每个controller都会有各自的作用域空间,不会相互干扰.
看下边这段html:
&div ng-app=&dataApp&&
单价: &input type=&number& min=0 ng-model=&price& ng-init=&price = 299&&&br&
数量: &input type=&number& min=0 ng-model=&quantity& ng-init=&quantity = 1&&&br&
总价: {{ quantity * price }}
你会惊喜地发现, 甚至不用写一行的JS代码, 即可完成计算并在界面展示结果.&
即: 在前端html中使用{{ }}括起来的变量, 是跟AngularJS中对应的controller作用域内的属性绑定在一起的. 实际上,{{}}等同于ng-bind指令, 即ng-bind=&myData&就能将NG中的myData数据跟前端对应元素绑定在一起.这样的话, 可以非常方便地做到从NG中获取任意数据并实时展示在页面上了.
另外, $scope对象还提供了一个$apply方法, 用于进行html页面上的更新, 使用方式为:
$scope.$apply(function(){
$scope.myValue = &NewValue&;
$scope对象, 我们可以理解为NG框架中的一个作用域对象, 在该作用域内可以做到数据和视图的相互绑定, 同时又能与其他$scope对象的作用域隔离开来.
当然, $scope也可以实现继承, 这部分内容在以后接触NG框架中其他对象的时候再分别做记录.
已发表评论数()
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
没有分页内容
图片无法显示
视频无法显示
与原文不一致IBM Bluemix
点击按钮,开始云上的开发!
developerWorks 社区
AngularJS是由Google发起的一款开源前端MVC框架,它拥有自己特有的一套数据组织和通信方式。本文主要讨论AngularJS的作用域和数据绑定机制,分析其不同的作用域特性,以及在作用域中实现通信的方法。
, 软件工程师,
朱盛浩是来自宁波IBM的一名软件工程师,致力于Mobile领域的开发和研究,同时对新兴开源框架非常感兴趣。
, 软件工程师,
IBM CDL的软件工程师,主要从事移动应用开发和SaaS应用开发。
, 软件工程师,
IBM CDL的软件工程师,主要从事SaaS,Cloud等应用开发,对移动应用技术有着浓厚兴趣。
AngularJS 简介AngularJS 是由 Google 发起的一款开源的前端 MVC 脚本框架,既适合做普通 WEB 应用也可以做 SPA(单页面应用,所有的用户操作都在一个页面中完成)。与同为 MVC 框架的 Dojo 的定位不同,AngularJS 在功能上更加轻量,而相比于 jQuery,AngularJS 又帮您省去了许多机械的绑定工作。在一些对开发速度要求高,功能模块不需要太丰富的非企业级 WEB 应用上,AngularJS 是一个非常好的选择。AngularJS 最为复杂同时也是最强大的部分就是它的数据绑定机制,这个机制帮助我们能更好的将注意力集中在数据的模型建立和传递上,而不是对底层的 DOM 进行低级的操作。AngularJS 作用域基于 jQuery 的传统 WEB 应用中,为了监听用户的输入等行为,需要为每一个 DOM 元素设置一个监听方法,也即是监听 DOM 上发生的各类事件,然后由 jQuery 做出回应并展示在页面上。这种方法简便直观,但是一旦 WEB 应用变得庞大而且复杂,那么监听代码就显得非常的机械而且冗余,更可怕的是,如果对于 DOM 的事件监听没有做好管理,那么很容易出现浏览器资源的泄露。针对以上所暴露的问题,AngularJS 用一系列指令来代替 jQuery 的事件绑定代码。为了能够组织好各类指令之间的协调工作而不出现数据混乱,AngularJS 在模型层上引申出作用域的概念,以配合控制器来实现对视图层的展现工作。作用域(Scope)AngularJS 中,作用域是一个指向应用模型的对象,它是表达式的执行环境。作用域有层次结构,这个层次和相应的 DOM 几乎是一样的。作用域能监控表达式和传递事件。在 HTML 代码中,一旦一个 ng-app 指令被定义,那么一个作用域就产生了,由 ng-app 所生成的作用域比较特殊,它是一个根作用域($rootScope),它是其他所有$Scope 的最顶层。清单 1. 生成根作用域&html&
&head&&script src="angular.min.js"&&/script&&/head&
&body data-ng-app="app"&...&/body&
&/html&除了用 ng-app 指令可以产生一个作用域之外,其他的指令如 ng-controller,ng-repeat 等都会产生一个或者多个作用域。此外,还可以通过 AngularJS 提供的创建作用域的工厂方法来创建一个作用域。这些作用域都拥有自己的继承上下文,并且根作用域都为$rootScope。在生成一个作用域之后,在编写 AngularJS 代码时,$scope 对象就代表了这个作用域的数据实体,我们可以在$scope 内定义各种数据类型,之后可以直接在 HTML 中以 {{变量名}} 方式来让 HTML 访问到这个变量,代码如下:清单 2. 简单的数据绑定&script&
angular.module('app', [])
.controller("ctrl", function ($scope) {
$scope.btns = {
ibm : 'ibm'
&body data-ng-app="app" &
&div data-ng-controller="ctrl"&
&button&{{btns.ibm}}&/button&
&/body&这就是 AngularJS 中最简单的数据绑定方式,同时也是应用最为广泛的数据绑定方式。继承作用域(Inherited Scope)AngularJS 在创建一个作用域时,会检索上下文,如果上下文中已经存在一个作用域,那么这个新创建的作用域就会以 JavaScript 原型继承机制继承其父作用域的属性和方法(有个例外是孤立作用域,下文讨论)。一些 AngularJS 指令会创建新的子作用域,并且进行原型继承: ng-repeat、ng-include、ng-switch、ng-view、ng-controller,
用 scope: true 和 transclude: true 创建的 directive。以下 HTML 中定义了三个作用域,分别是由 ng-app 指令所创建的$rootScope,parentCtrl 和 childCtrl 所创建的子作用域,这其中 childCtrl 生成的作用域又是 parentCtrl 的子作用域。清单 3. 作用域的继承实例&body data-ng-app="app"&
&div data-ng-controller="parentCtrl"&
&input data-ng-model="args"&
&div data-ng-controller="childCtrl"&
&input data-ng-model="args"&
&/body&继承作用域符合 JavaScript 的原型继承机制,这意味着如果我们在子作用域中访问一个父作用域中定义的属性,JavaScript 首先在子作用域中寻找该属性,没找到再从原型链上的父作用域中寻找,如果还没找到会再往上一级原型链的父作用域寻找。在 AngularJS 中,作用域原型链的顶端是$rootScope,AnguarJS 将会寻找到$rootScope 为止,如果还是找不到,则会返回 undefined。我们用实例代码说明下这个机制。首先,我们探讨下对于原型数据类型的作用域继承机制:清单 4. 作用域继承实例-原始类型数据继承&script type="text/javascript"&
angular.module('app', [])
.controller('parentCtrl', ['$scope', function($scope) {
$scope.args = 'IBM DeveloperWorks';
.controller('childCtrl', ['$scope', function($scope) {
&body data-ng-app="app"&
&div data-ng-controller="parentCtrl"&
&input data-ng-model="args"&
&div data-ng-controller="childCtrl"&
&input data-ng-model="args"&
&/body&运行页面,我们得到以下的结果:图 1. 页面运行结果。这个结果我们非常好理解,虽然在 childCtrl 中没有定义具体的 args 属性,但是因为 childCtrl 的作用域继承自 parentCtrl 的作用域,因此,AngularJS 会找到父作用域中的 args 属性并设置到输入框中。而且,如果我们在第一个输入框中改变内容,内容将会同步的反应到第二个输入框:图 2. 改变第一个输入框的内容后页面运行结果假如我们修改第二个输入框的内容,此时会发生什么事情呢?答案是第二个输入框的内容从此将不再和第一个输入框的内容保持同步。在改变第二个输入框的内容时,因为 HTML 代码中 model 明确绑定在 childCtrl 的作用域中,因此 AngularJS 会为 childCtrl 生成一个 args 原始类型属性。这样,根据 AngularJS 作用域继承原型机制,childCtrl 在自己的作用域找得到 args 这个属性,从而也不再会去寻找 parentCtrl 的 args 属性。从此,两个输入框的内容所绑定的属性已经是两份不同的实例,因此不会再保持同步。图 3. 改变第二个输入框的内容后页面运行结果假如我们将代码做如下修改,结合以上两个场景,思考下会出现怎样的结果?清单 5. 作用域继承实例-对象数据继承&script type="text/javascript"&
angular.module('app', [])
.controller('parentCtrl', ['$scope', function($scope) {
$scope.args = {};
$scope.args.content = 'IBM DeveloperWorks';
.controller('childCtrl', ['$scope', function($scope) {
&body data-ng-app="app"&
&div data-ng-controller="parentCtrl"&
&input data-ng-model="args.content"&
&div data-ng-controller="childCtrl"&
&input data-ng-model="args.content"&
&/body&答案是无论改变任何一个输入框的内容,两者的内容始终同步。根据 AngularJS 的原型继承机制,如果 ng-model 绑定的是一个对象数据,那么 AngularJS 将不会为 childCtrl 创建一个 args 的对象,自然也不会有 args.content 属性。这样,childCtrl 作用域中将始终不会存在 args.content 属性,只能从父作用域中寻找,也即是两个输入框的的变化其实只是在改变 parentCtrl 作用域中的 args.content 属性。因此,两者的内容始终保持同步。我们再看一个例子,这次请读者自行分析结果。清单 6. 作用域继承实例-不再访问父作用域的数据对象。&script type="text/javascript"&
angular.module('app', [])
.controller('parentCtrl', ['$scope', function($scope) {
$scope.args = {};
$scope.args.content = 'IBM DeveloperWorks';
.controller('childCtrl', ['$scope', function($scope) {
$scope.args = {};
$scope.args.content = 'IBM DeveloperWorks';
&body data-ng-app="app"&
&div data-ng-controller="parentCtrl"&
&input data-ng-model="args.content"&
&div data-ng-controller="childCtrl"&
&input data-ng-model="args.content"&
&/body&答案是两个输入框的内容永远不会同步。孤立作用域(Isolate Scope)孤立作用域是 AngularJS 中一个非常特殊的作用域,它只在 directive 中出现。在对 directive 的定义中,我们添加上一个 scope:{} 属性,就为这个 directive 创建出了一个隔离作用域。清单 7. directive 创建出一个孤立作用域angular.module('isolate', []).directive("isolate", function () {
scope : {},
})孤立作用域最大的特点是不会原型继承其父作用域,对外界的父作用域保持相对的独立。因此,如果在定义了孤立作用域的 AngularJS
directive 中想要访问其父作用域的属性,则得到的值为 undefined。代码如下:清单 8. 孤立作用域的隔离性&script type="text/javascript"&
angular.module('app', [])
.controller('ctrl', ['$scope', function($scope) {
$scope.args = {};
.directive("isolateDirective", function () {
scope : {},
link : function($scope, $element, $attr) {
console.log($scope.$args); //输出 undefined
&body data-ng-app="app"&
&div data-ng-controller="ctrl"&
&div data-isolate-directive&&/div&
&/body&上面的代码中通过在 directive 中声明了 scope 属性从而创建了一个作用域,其父作用域为 ctrl 所属的作用域。但是,这个作用域是孤立的,因此,它访问不到父作用域的中的任何属性。存在这样设计机制的好处是:能够创建出一些列可复用的 directive,这些 directive 不会相互在拥有的属性值上产生串扰,也不会产生任何副作用。AngularJS 孤立作用域的数据绑定在继承作用域中,我们可以选择子作用域直接操作父作用域数据来实现父子作用域的通信,而在孤立作用域中,子作用域不能直接访问和修改父作用域的属性和值。为了能够使孤立作用域也能和外界通信,AngularJS 提供了三种方式用来打破孤立作用域“孤立”这一限制。单向绑定(@ 或者 @attr)这是 AngularJS 孤立作用域与外界父作用域进行数据通信中最简单的一种,绑定的对象只能是父作用域中的字符串值,并且为单向只读引用,无法对父作用域中的字符串值进行修改,此外,这个字符串还必须在父作用域的 HTML 节点中以 attr(属性)的方式声明。使用这种绑定方式时,需要在 directive 的 scope 属性中明确指定引用父作用域中的 HTML 字符串属性,否则会抛异常。示例代码如下:清单 9. 单向绑定示例&script&
angular.module('isolateScope', [])
.directive("isolateDirective", function () {
replace : true,
template: '&button&{{isolates}}&/button&',
isolates : '@',
link : function($scope, $element, $attr) {
$scope.isolates = "DeveloperWorks";
.controller("ctrl", function ($scope) {
$scope.btns = 'IBM';
&body data-ng-app="isolateScope" &
&div data-ng-controller="ctrl"&
&button&{{btns}}&/button&
&div data-isolate-directive data-isolates="{{btns}}"&&/div&
&/body&简单分析下上面的代码,通过在 directive 中声明了 scope:{isolates:'@'} 使得 directive 拥有了父作用域中 data-isolates 这个 HTML 属性所拥有的值,这个值在控制器 ctrl 中被赋值为'IBM'。所以,代码的运行结果是页面上有两个名为 IBM 的按钮。我们还注意到 link 函数中对 isolates 进行了修改,但是最终不会在运行结果中体现。这是因为 isolates 始终绑定为父作用域中的 btns 字符串,如果父作用域中的 btns 不改变,那么在孤立作用域中无论怎么修改 isolates 都不会起作用。引用绑定(&或者&attr)通过这种形式的绑定,孤立作用域将有能力访问到父作用域中的函数对象,从而能够执行父作用域中的函数来获取某些结果。这种方式的绑定跟单向绑定一样,只能以只读的方式访问父作用函数,并且这个函数的定义必须写在父作用域 HTML 中的 attr(属性)节点上。这种方式的绑定虽然无法修改父作用域的 attr 所设定的函数对象,但是却可以通过执行函数来改变父作用域中某些属性的值,来达到一些预期的效果。示例代码如下:清单 10. 引用绑定示例&script&
angular.module('isolateScope', [])
.directive("isolateDirective", function () {
replace : true,
isolates : '&',
link : function($scope, $element, $attr) {
var func = $scope.isolates();
.controller("ctrl", function ($scope) {
$scope.func = function () {
console.log("IBM DeveloperWorks");
&body data-ng-app="isolateScope" &
&div data-ng-controller="ctrl"&
&div data-isolate-directive data-isolates="func"&&/div&
&/body&这个例子中,浏览器的控制台将会输出一段“IBM DeveloperWorks”文字。上面的代码中我们在父作用域中指定了一个函数对象$scope.func,在孤立作用域中通过对 HTML 属性的绑定从而引用了 func。需要注意的是 link 函数中对 func 对象的使用方法,$scope.isolates 获得的仅仅是函数对象,而不是调用这个对象,因此我们需要在调用完$scope.isolates 之后再调用这个函数,才能得到真正的执行结果。双向绑定(=或者=attr)双向绑定赋予 AngularJS 孤立作用域与外界最为自由的双向数据通信功能。在双向绑定模式下,孤立作用域能够直接读写父作用域中的属性和数据。和以上两种孤立作用域定义数据绑定一样,双向绑定也必须在父作用域的 HTML 中设定属性节点来绑定。双向绑定非常适用于一些子 directive 需要频繁和父作用域进行数据交互,并且数据比较复杂的场景。不过,由于可以自由的读写父作用域中的属性和对象,所以在一些多个 directive 共享父作用域数据的场景下需要小心使用,很容易引起数据上的混乱。示例代码如下:清单 11. 双向绑定示例&script&
angular.module('isolateScope', [])
.directive("isolateDirective", function () {
replace : true,
template: '&button&{{isolates}}&/button&',
isolates : '=',
link : function($scope, $element, $attr) {
$scope.isolates.ibm = "IBM";
.controller("ctrl", function ($scope) {
$scope.btns = {
ibm : 'ibm',
dw : 'DeveloperWorks'
&body data-ng-app="isolateScope" &
&div data-ng-controller="ctrl"&
&button&{{btns.dw}}&/button&
&button&{{btns.ibm}}&/button&
&div data-isolate-directive data-isolates="btns"&&/div&
&/body&上面的代码运行的结果是浏览器页面上出现三个按钮,其中第一个按钮标题为“DeveloperWorks”,第二和第三个按钮的标题为“IBM”。初始时父作用域中的$scope.btns.ibm 为小写的“ibm”,通过双向绑定,孤立作用域中将父作用域的 ibm 改写成为大写的“IBM”并且直接生效,父作用域的值被更改。总结由于 AngularJS 框架的轻量性和其清晰的 MVC 特点使得其在推出之后就大受欢迎,实践中也很容易上手。AngularJS 比较难以掌握和理解的就是其作用域和绑定机制,本文重点将作用域和绑定机制做了分析与讨论,希望读者能够理解并熟练掌握这块内容。
参考资料 参考了解更多关于作用域的介绍参考了解更多关于作用域和数据绑定的中文介绍参考中国了解更多其他关于 AngularJS 的文章:查找丰富的操作信息、工具和项目更新,帮助您掌握开源技术并将其用于 IBM 产品。
加入 ,查看开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户交流。
developerWorks: 登录
标有星(*)号的字段是必填字段。
保持登录。
单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件。
在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。
所有提交的信息确保安全。
选择您的昵称
当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。昵称长度在 3 至 31 个字符之间。
您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。
标有星(*)号的字段是必填字段。
(昵称长度在 3 至 31 个字符之间)
单击提交则表示您同意developerWorks 的条款和条件。 .
所有提交的信息确保安全。
文章、教程、演示,帮助您构建、部署和管理云应用。
立即加入来自 IBM 的专业 IT 社交网络。
为灾难恢复构建应用,赢取现金大奖。
static.content.url=/developerworks/js/artrating/SITE_ID=10Zone=Open source, Web developmentArticleID=1004048ArticleTitle=AngularJS 作用域与数据绑定机制publish-date=

我要回帖

更多关于 js实现双向数据绑定 的文章

 

随机推荐