angularjs 绑定策略怎么立即获取数据绑定的值

angular学习(12)
AngularJS 1.3版本正式发布,其中添加了很多的性特性,同时也对之前的一些bug做了修复,最重要的是其中包含一些突破性的变化。其中最重要的一项就是添加了一次性数据绑定。等等,一次性数据绑定?这听起来似乎和AngularJS一直宣扬的双向数据绑定思想完全背离了吗?当然,AngularJS的双向数据绑定一直是AngularJS最重要的特性之一。然而,为了实现双向数据绑定,AngularJS需要为每一个绑定的值都设置一个监听器(watcher)。当需要绑定的数据越来越多时,成堆的监听器会对应用的性能造成很坏的影响。在具体了解一次性数据绑定之前,先让我们来简单的回顾一下AngularJS中双向数据绑定究竟是怎么一回事。
理解双向数据绑定和监听器
为了实现双向数据绑定,AngularJS使用了$watch&API来观察期作用域中的模型变化。具体的作用域取决于你的代码如何编写。如果你没有创建一个自作用域,就是说没有使用ngController指令在你的DOM和你的控制器代码之间创建一个关联,你可能处理的是跟作用域$rootScope,这个作用域由ngApp自动创建,并且是应用中所有作用域的父作用域,当然,如果你选择手动启动AngularJS,那情况就另当别论了。
每当你创建了一个数据绑定时,AngularJS就会自动创建一个监听器来监听这个数据的变化。比如说下面这个简单的例子:
&p&Hello {{name}}!&/p&
在这个例子中,我们使用了插值指令,这个指令会注册一个监听器来监听相应作用域中属性name的变化,并在该属性发生变化时将它实时反应到DOM中。
添加下面的代码,你的name属性将会自动的被赋值为Pascal:
angular.module('myApp', [])
.run(function ($rootScope) {
$rootScope.name = &Pascal&;
通过上面的代码,我们就成功的使用了插值指令创建了在试图上创建了一个数据绑定。现在,如果name属性发生变化,视图将会自动发生更新。比如说我们添加下面的代码,在按钮点击是修改name的值:
&button ng-click=&name = 'Christoph'&&Click me!&/button&
此时,点击按钮,我们可以将name的值修改为Christoph,同时我们会触发一个$digest循环来更新DOM中相应的部分。在上面的例子中,你看的知识单向数据绑定。然而,你完全可以使用ngModel指令来将视图中发生的变化实时的反应到模型中。
上面的双向绑定魔法的实现完全依赖于$digest循环,当$digest循环被触发时,AngularJS将会去处理遍历当前作用域和子作用域中的所有监听器,然后通过检查模型中发生的变化来更新DOM中的值,直到模型不再发生变化为止。一旦$digest循环执行完成,浏览器会重新渲染DOM来反应模型数据变化。
太多监听器存在的问题
现在,我们大概了解了AngularJS的数据绑定机制,你可能会问我们为何还需要一次性数据绑定。
由于AngularJS使用监听器来实现数据绑定。当监听器越来越多时,可能会出现一些性能上的问题。由于在注册监听器使,同时会注册一个回调函数,以便在$digest循环执行时能够相应的更新视图。也就是说,监听器越多,AngularJS需要处理的回调函数也就越多。
现在假设在视图中有很多值需要被AngularJS处理。比如说像上面使用插值指令来进行数据绑定,虽然我们可能并不想让这个值只绑定一次,比如说上面的Pascal,在应用代码执行的整个过程中这个属性都不会发生改变,但是AngularJS默认依然会在这个属性上绑定一个监听器和回调函数。因此,在$digest时,AngularJS依然会去特意的关注这个值,这实在是有些过头了。
一次性数据绑定(One-time bindings)
这就是我们需要一次性数据绑定的原因。在AngularJS的文档中,我们可以清楚的了解到这个新特性的作用:
一次性数据绑定表达式可以在数据稳定之后,不需要在$digest循环中重计算…
一次性数据绑定的出现解决了前面提到的由监听器太多带来的性能问题。那么我们应该如何使用一次性数据绑定呢?
使用一次性数据绑定非常的简单,我们只需要在表达式之前加上双冒号::即可。比如,前面我们使用了插值指令将name属性绑定到了视图中:
&p&Hello {{name}}!&/p&
使用一次性数据绑定,我们这样写:
&p&Hello {{::name}}!&/p&
在AngularJS 1.3版本中,你可以在任何AngularJS的表达式中使用一次性数据绑定。即使在诸如ng-repeat这样严重依赖于双向绑定的指令中,你依然可以使用它。在自定义的指令中,你可以在属性中这样使用:
&custom-directive two-way-attribute=&::oneWayExpression&&&/custom-directive&
一次性数据绑定的出现解决了AngularJS中饱受诟病的性能问题,官方版本原生支持也使我们不需要在使用bindonce这样的第三方模块。从一次性数据绑定出现在原生代码中,我们可以看到AngularJS在不断从社区中吸取好的想法,并及时作出改变。AngularJS
1.3只是一个AngularJS不断进化的一个小阶段,在官方承诺的AngularJS 2.0中,我们可以期待到时它带给我们的惊喜。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:25824次
积分:1740
积分:1740
排名:第17420名
原创:118篇
转载:81篇
译文:21篇
(1)(6)(14)(11)(1)(3)(7)(22)(14)(10)(7)(6)(10)(1)(2)(2)(16)(4)(29)(35)(23)让Avalonjs/angularjs/MVVM数据刷新绑定提升速度/性能20倍 - IT大师
& 16:17:29
修改记录:1、解决数组内包含子数组会引起内存泄漏的问题。Avalonjs/angularjs类似的MVVM框架,在每次刷新绑定数据时,性能很弱,数据量越大越明显。如定时刷新数据并赋值:vm.MyList&=&[];
vm.GetList&=&function(){
&&&&$.post(&url&,param,function(result){
&&&&&&&&//result为服务器返回的数据
&&&&&&&&//此步骤非常损耗性能
&&&&&&&&vm.MyList&=&
&&&&&&&&//新的解决方案,速度直接提升3-20倍。数据量越大提升效果越明显。
&&&&&&&&//本人亲测14M的数据,上面绑定方式需要60秒,下面方式只需3秒。
&&&&&&&&//vm.MyList.Bind(result);
//定时刷新数据
setTimeout(vm.GetList,5000);对比图:1)vm.MyList =方式:FPS会越来越低,直到1fps2)vm.MyList.Bind(result);方式:FPS会越来越高,直到20fps最后别忘记在页面绑定上加上:例:&div&ms-repeat=&MyList&&ms-if-loop=&el.__sign&!=&'del'&&This&is&content.&/div&附上本人最后封装的Bind核心代码://-------------avalonJs绑定封装&by&
//Last&Update:。解决数组内包含子数组会引起内存泄漏的问题。
Array.prototype.Bind&=&function&(newData)&{
&&&&var&thisLength&=&this.
&&&&var&newDataLength&=&newData.
&&&&var&maxCount&=&newDataLength&&&thisLength&?&newDataLength&:&thisL
&&&&var&tempBit&=&newDataLength&&=&thisL
&&&&for&(var&i&=&0;&i&&&maxC&i++)&{
&&&&&&&&//如果新数据&大于等于&老数据
&&&&&&&&if&(tempBit)&{
&&&&&&&&&&&&if&(i&&=&thisLength)&{
&&&&&&&&&&&&&&&&//如果包含子数组,则需要给子数组的object声明__sign
&&&&&&&&&&&&&&&&//目前__sign只支持二级子数组,需要递归实现无限子数组。
&&&&&&&&&&&&&&&&for&(var&key1&in&newData[i])&{
&&&&&&&&&&&&&&&&&&&&if&(avalon.type(newData[i][key1])&==&&array&)&{
&&&&&&&&&&&&&&&&&&&&&&&&for&(var&j&=&0;&j&&&newData[i][key1].&j++)&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&newData[i][key1][j].__sign&=&&&;
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&}&else&{
&&&&&&&&&&&&&&&&&&&&&&&&newData[i].__sign&=&&&;
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&//老数据循环完了,这时候把新数据插入到老数据
&&&&&&&&&&&&&&&&this.push(newData[i]);
&&&&&&&&&&&&}&else&{
&&&&&&&&&&&&&&&&//更新老数据
&&&&&&&&&&&&&&&&this[i].__sign&=&&&;
&&&&&&&&&&&&&&&&this.Update(i,&newData[i]);
&&&&&&&&&&&&}
&&&&&&&&&&&&//如果老数据大于新数据
&&&&&&&&else&{
&&&&&&&&&&&&if&(i&&=&newDataLength)&{
&&&&&&&&&&&&&&&&//新数据循环完了,标记老数据为已删除
&&&&&&&&&&&&&&&&this[i].__sign&=&&del&;
&&&&&&&&&&&&}&else&{
&&&&&&&&&&&&&&&&//更新老数据
&&&&&&&&&&&&&&&&this[i].__sign&=&&&;
&&&&&&&&&&&&&&&&this.Update(i,&newData[i]);
&&&&&&&&&&&&}
//新增:解决数组内包含子数组会引起内存泄漏的问题。
Array.prototype.Update&=&function&(index,&val)&{
&&&&var&valueType&=&avalon.type(val);
&&&&if&(val&&&&val.$model)&{
&&&&&&&&val&=&val.$
&&&&var&target&=&this[index];
&&&&if&(valueType&===&&object&)&{
&&&&&&&&for&(var&k&in&val)&{
&&&&&&&&&&&&if&(!target.hasOwnProperty(k))&{
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&}
&&&&&&&&&&&&if&(avalon.type(val[k])&==&&array&)&{
&&&&&&&&&&&&&&&&//第一种:这种方式仍然会内存泄漏
&&&&&&&&&&&&&&&&//target[k].clear().push.apply(target[k],&val[k]);
&&&&&&&&&&&&&&&&//第二种:递归方式,完美解决内存泄露
&&&&&&&&&&&&&&&&target[k].Bind(val[k]);
&&&&&&&&&&&&}&else&{
&&&&&&&&&&&&&&&&target[k]&=&val[k];
&&&&&&&&&&&&}
&&&&}&else&if&(valueType&===&&array&)&{
&&&&&&&&target.clear().push.apply(target,&val);
&&&&}&else&if&(target&!==&val)&{
&&&&&&&&this[index]&=&
&&&&&&&&//notifySubscribers(this,&&set&,&index,&val);
};源码及Demo对比测试源码:本文原创地址:&转载请保留此链接,谢谢!
文章链接:
原创说明:转载原创文章时请保留原文链接,谢谢!
转载说明:本站转载文章均标明文章来源,若本篇转载侵犯了您的权益,请联系站长删除!
交流Q群:
开源组件:、双向数据绑定---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个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致javaweb(4)
javascript(3)
class="tab-pane fade " id="mission"&
ui-tinymce="defaultTinymceOptions"
ng-model="shipInfo.mission"&&
define(['angular','app','ztree', './jclst-res'], function(ng, app) {
app.register.controller('info.jcmgr.jclst',['$scope', 'jclstRes','gritterService',function($scope,jclstRes,gritterService,orgUtil,jxUtil) {
var gritters = gritterService.Light(gritterService.Gritters);
$scope.add = function(){
$scope.ship = {};
$scope.shipInfo = {};
$scope.addorgflag = true;
$scope.editorgflag = false;
$scope.jcEditor.visible = true;
$scope.jcEditor = {
'title': '编辑信息',
'iconClass': 'fa fa-laptop',
'view': 'info.jcmgr.jcedit',
'width': 900,
'freeDom': true,
'height':520,
'buttons': [
'buttonClass': 'btn-info btn-sm',
'iconClass':'fa fa-check-circle-o',
'text': '保存',
'onclick': function(jceditingForm) {
if (!jceditingForm.$valid) {
gritters.error({
'text':'无法保存,请检查表单内容。',
'title':'信息'
var shipunion = {
'ship':$scope.ship,
'shipInfo':$scope.shipInfo
jclstRes.edit({},shipunion,function(e){
if(e.exception){
gritters.error({
'title':'信息',
'text':e.exception
gritters.success({
'title': '信息',
'text': '保存成功'
$scope.jcEditor.visible = false;
$scope.searchPage(1);
'buttonClass': 'btn-default btn-sm',
'iconClass':'fa fa-times-circle-o',
'text': '关闭',
'onclick': function() {
$scope.jcEditor.visible = false;
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:4768次
排名:千里之外
原创:21篇
转载:10篇
(2)(2)(5)(1)(4)(1)(2)(1)(2)(1)(2)(2)(1)(5)(1)&本篇我们看一下AngularJS中的数据绑定。虽然我们直到这篇才提到数据绑定,但事实上在前面几篇中我们已经非常熟练的运用AngularJS的数据绑定功能了!
ngBind(ng-bind)/ {{ expression }}:
1 &!DOCTYPE &
&script src="/Scripts/angular.js"&&/script&
6 &body ng-app&
&input ng-model="yourName" /&
Hello, {{yourName}}
Use ngBind to display: &span ng-bind="yourName"&&/span&
14 &/body&
15 &/html&
如果你已经看过前面几篇文章,我相信你已经非常熟悉这样的代码了。AngualrJS中使用ngBind进行数据绑定,但是我们更多的会使用Expression(即{{expression}}这样的写法)替代ngBind,这种写法更简便直观。
AngularJS还提供了其他几种数据绑定方式:
ngBindHtml:
1 &!DOCTYPE &
&script src="/Scripts/angular.js"&&/script&
&script src="/Scripts/angular-sanitize.js"&&/script&
&script type="text/javascript"&
(function () {
var app = angular.module('twowayBindingTest', ['ngSanitize']);
app.controller('myController', ['$scope', function ($scope) {
$scope.myHtml = "This is a link: &a href=\"#\"&Mylink&/a&";
15 &/head&
16 &body ng-app="twowayBindingTest" ng-controller="myController"&
&span ng-bind-html="myHtml"&&/span&
20 &/body&
21 &/html&
ngBindHtml(ng-bind-html)可以将一个字符串以安全的方式插入到页面中并显示成Html。
ngBindHtml将强制使用angular-santitize服务进行安全检查,由于并非包含在AngualrJS核心库中,因此需要引入angular-santitize.js文件,并在定义ngModule时添加对于ngSantitize的依赖声明。
关于AngularJS的服务我们将在今后再统一讨论,这里就不展开了。
ngBindTemplate:
1 &!DOCTYPE &
&script src="/Scripts/angular.js"&&/script&
6 &body ng-app&
Name:&input ng-model="yourName" /&
Age:&input ng-model="yourAge" /&
&span ng-bind-template="This is {{yourName}}, I'm {{yourAge}} years old."&&/span&
13 &/body&
14 &/html&
ngBindTemplate(ng-bind-template)与ngBind不同之处在于:ngBind只能单个绑定变量,且变量无需使用双括号&{{}}&,而ngBindTemplate则可以绑定一个模板,模板中可以包含多个AngularJS的表达式:&{{expression}}&。
ngNonBindable:
1 &!DOCTYPE &
&script src="/Scripts/angular.js"&&/script&
6 &body ng-app&
&div ng-non-bindable&This will not be changed: {{1 + 2}}&/div&
当然,如果你页面上正好有"{{ my content }}" 这样的内容,不需要执行AngularJS帮你进行编译和计算,使用ngNonBindable(ng-non-binable),AngularJS会自动忽略该内容。
使用ngModel实现Twoway Binding:
1 &!DOCTYPE &
&script src="/Scripts/angular.js"&&/script&
&script type="text/javascript"&
(function () {
var app = angular.module('twowayBindingTest', []);
app.controller('myController', ['$scope', function ($scope) {
$scope.students = [];
$scope.addStudent = function (stu) {
$scope.students.push(stu);
$scope.stu = {};
$scope.removeStudent = function (index) {
$scope.students.splice(index, 1);
25 &/head&
26 &body ng-app="twowayBindingTest" ng-controller="myController"&
&p&Name:&input ng-model="stu.name"&&/input&&/p&
&p&Age:&input ng-model="stu.age"&&/input&&/p&
&input type="button" ng-click="addStudent(stu)" value="Add" /&
&div ng-repeat="stu in students"&
&span ng-hide="editMode"&{{stu.name}}&/span&
&input type="text" ng-show="editMode" ng-model="stu.name" /&
&span ng-hide="editMode"&{{stu.age}}&/span&
&input type="text" ng-show="editMode" ng-model="stu.age" /&
&input type="button" value="Edit" ng-hide="editMode" ng-click="editMode = true" /&
&input type="button" value="Save" ng-show="editMode" ng-click="editMode = false" /&
&input type="button" value="Remove" ng-hide="editMode" ng-click="removeStudent($index)" /&
45 &/body&
46 &/html&
上面的代码就展示了AngularJS中的双向绑定的用法。如果你仔细看完代码并执行一下,就会发现双向绑定的奇妙之处。
&input type="button" value="Edit" ng-hide="editMode" ng-click="editMode = true" /&
&input type="button" value="Save" ng-show="editMode" ng-click="editMode = false" /&
编辑、保存按钮的代码非常简单,都不需要添加业务逻辑,因为是双向绑定,当改变输入框内的内容并点击Save之后,由于span中的stu.name和stu.age以及$scope.students中相应的记录的name和age指向了相同的ng-model,因此AngularJS会自动完成这三者之间的同步变更。因此你都不需要编写额外的代码去完成编辑、保存这样的行为,这就是双向绑定带来的奇妙体验。
本篇讲述了AngularJS中的数据绑定,是不是很简单但也超级实用呢?
AngularJS官方文档:
CodeSchool快速入门视频:
CodeProject文章:
阅读(...) 评论()}

我要回帖

更多关于 angularjs 绑定事件 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信