angularJS之$apply()方法
来源:互联网 发布:快速复制软件哪个好 编辑:程序博客网 时间:2024/05/16 19:55
转载自:http://www.cnblogs.com/penghongwei/p/3398361.html
这几天,根据buddy指定的任务,要分享一点angular JS的东西。对于一个在前端属于纯新手的我来说,Javascript都还是一知半解,要想直接上手angular JS,遇到的阻力还真是不少。不过我相信,只要下功夫,即使是反人类的设计也不是什么大的问题。
Okay,废话不多说。为了弄明白angular JS为何物,我先是从Scope开始。那么什么是Scope呢?借用官方文档的一段话:
“scope is an object that refers to the application model. It is an execution context for expressions. Scopes are arranged in hierarchical structure which mimic the DOM structure of the application. Scopes can watch expressions and propagate events.”
看完后,类比到其他的编程语言上,感觉Scope就像是Data Model的作用域一样,为Expressions的执行提供上下文,暂且先这么理解吧。
- Scope的特性
接下来,看看Scope有哪些特性呢?
- Scope提供$watch方法监视Model的变化。
- Scope提供$apply方法传播Model的变化。
- Scope可以继承,用来隔离不同的application components和属性访问权限。
- Scope为Expressions的计算提供上下文。
对于这四点特性,因为我之前学习过ActionScript、C++、Java,所以第一、三、四点不难理解,唯独第二点感觉有点云里雾里。本着打破沙锅问到底的原则,我还是通过Google搜到了一些东西。对于有经验的老手,板砖请轻拍!
- 源起Javascript
首先,乍一看,
var button = document.getElementById('clickMe');function buttonClicked () { alert('the button was clicked');}button.addEventListener('click', buttonClicked);function timerComplete () { alert('timer complete');}setTimeout(timerComplete, 5000);
当加载Javascript代码时,先先找一个一个id叫“clickMe”的按钮,然后添加一个监听器,然后设置超时。等待5秒,会弹出一个对话框。如果刷新页面并立即点击clickMe按钮,会弹出一个对话框,如果你不点击OK,timerComplete函数永远没有机会执行。
- 如何更新bindings
好了,扯了一些看似不相关的东西之后,我们回归正题。angular JS是怎么知道什么时候数据的变化和页面需要更新的呢?代码需要知道什么时候数据被修改了,但是现在又没有一种方法直接去通知说某个对象上的数据变了(尽管ECMAScript 5正在尝试解决这一问题,但也还是处于实验阶段)。而目前比较主流的策略有以下有两种解决方案。一种是需要用特殊的对象,让所有的数据都只能通过调用对象的方法设置,而不是直接通过property指定。这样的话,所有的修改就可以被记录下来了,就知道什么时候页面需要更新了。这样做的弊端就是我们必须去继承一个特殊的对象。对于赋值也只能通过object.set('key', 'value')而不是object.key=value的方式。在框架中,像EmberJS和KnockoutJS就是这么干的(虽然我都没接触过——囧)。另一种就是angular JS采用的方式,在每一次Javascript代码执行序列执行结束后都去检查是否有数据的改变。这看起来似乎并不高效,甚至严重影响性能。但是angular JS采用了一些比较巧妙的手段解决了这个问题(还没研究过,目前尚不明确)。这么做的好处就是,我们可以随便使用任意对象,对于赋值方式也没有限制,而且对于数据的改变也能觉察到。
对于angular JS采取的这种解决方案,我们关心的是什么时候数据发生了变化,而这也正是
- 什么时候用$apply()
还是那个问题,那我们到底什么时候需要去调用
[HTML]
<div ng:app ng-controller="Ctrl">{{message}}</div>
[Javascript]
functionCtrl($scope) { $scope.message ="Waiting 2000ms for update"; setTimeout(function () { $scope.message ="Timeout called!"; // AngularJS unaware of update to $scope }, 2000); }
上面的代码执行后页面上会显示:Waiting 2000ms for update。显然数据的更新没有被angular JS觉察到。
接下来,我们将Javascript的代码稍作修改,用
[Javascript]
functionCtrl($scope) { $scope.message ="Waiting 2000ms for update"; setTimeout(function () { $scope.$apply(function () { $scope.message ="Timeout called!"; }); }, 2000); }
这次与之前不同的是,页面上先会显示:Waiting 2000ms for update,等待2秒后内容会被更改为:Timeout called! 。显然数据的更新被angular JS觉察到了。
NOTE:我们不应该这样做,而是用angular JS提供的
- 科学是把双刃剑
最后,我们再来瞅一眼
function$apply(expr) { try { return$eval(expr); } catch(e) { $exceptionHandler(e); } finally { $root.$digest(); }}
它会捕获所有的异常并且不会再抛出来(我们应该是可以获得错误的通知,但是失去了再次处理异常的机会),最后都会调用$digest()方法。
- 总结一下
$apply()方法可以在angular框架之外执行angular JS的表达式,例如:DOM事件、setTimeout、XHR或其他第三方的库。这仅仅是个开始,水还有很深,欢迎大家一起来deep dive!
===================================================================
- 【题外话】
If you are assigning a string containing a . char, you will need to use the $apply(fn) method or you will get an error.
Example:
var imagename = "myimage.png";$scope.$apply($scope.image = imagename);
The code above will throw an error because Angular will interpret the string as an object. Using the function method this does not happen.
Example:
$scope.$apply(function () { $scope.image = imagename;});
作者:make dream
出处:http://www.cnblogs.com/penghongwei/
本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
- angularJS之$apply()方法
- angularJS之$apply()方法
- angularJS中$apply()方法详解之什么时候用$apply()
- (12)AngularJS 1.X 之$watch和$apply方法
- angularJS中$apply()方法详解
- angularjs $scope.$apply 方法详解
- angularJS中$apply()方法详解
- angularJS中$apply()方法详解
- angularJS--apply() 、digest()和watch()方法
- AngularJs $apply
- angularJs $apply
- AngularJS学习之$digest循环和$apply
- Angularjs $scope 里面的$apply方法 和 $watch方法
- angularJS学习小结——$apply方法和$watch方法
- Angularjs $scope 里面的$apply 方法 和 $watch 方法
- angularJS $scope的$apply方法实现model刷新
- AngularJs学习笔记(3)--$scope中的$apply和$digest方法
- AngularJS初涉之$parsers与$formatters、$apply与$digest
- button.PerformClick()与button_Click(sender,e)的小区别
- Ogre程序添加控制台显示
- Ruby源文件指引
- net 内存泄露和内存溢出
- android 如何做到完全退出应用程序
- angularJS之$apply()方法
- 分享一个网上的图片识别程序
- Rtsp发送ANNOUNCE到Darwin时,RTSP/1.0 401 Unauthorized
- C-Ruby源码分析-1
- java类型安全和线程安全
- 并查集及例题题解
- C-Ruby源码分析-2( RNode 结构浅析)
- Oracle数据库学习 第一天
- org.apache.commons.dbcp.DelegatingPreparedStatement.setBinaryStream(ILjava/io/InputStream;J)V