文档章节

AngularJS,为什么我们要使用$apply()?在什么时候使用?

随风所欲
 随风所欲
发布于 2015/11/24 14:28
字数 791
阅读 68
收藏 1

初学angular的时候,我们在使用中经常遇到更改scope里的值,但是model没有相应的更新。于是我们发现angular有一个$apply()方法,来update我们的model.但是我们使用过后,有时候控制台会报出错误:

Error: $digest / $apply already in progress。

然后我们百度得到的解决方案是:

if(!$scope.$$phase) { 
    //$digest or $apply 
}

一直一来,我在我初学angular后做的项目里也是这么干的。直到某一天我看到了有人说:

然后我开始反思,我的程序是是不是哪里写的有问题?在我翻看了很多大神的文章后,我大致理解了。

为什么我们会使用到$apply()?

        一般情况,我们在 controller初始化、使用$http的callbacks、类似ng-click这类的ng-*事件时,angular都会用$apply()包起来当里面的function或者一个Angular expression string执行后,就会去调用$scope.$digest()更新数据的绑定。所以是不需要你去主动调用$apply()的,且你在$apply()里面调用$apply()将会抛错的。就是如你们看到的$digest / $apply already in progress

        如果我们用到了$apply()那么应该是以下情况:

        a.  代码处于$digest loop(更新周期)外,比如在"link"指令(directive)响应函数内部使用。也就是说,只能在$controller之外调用$apply,这样它就可以访问到HTML或其他控制器的声明代码 - 比如apply调用link指令并触发相应功能,这时侯是肯定在$digest loop之外的。

        b.  在你的代码块里面还包含有新的函数块,比如:

function Ctrl($scope) {
  $scope.message = "Waiting 2000ms for update";    
    setTimeout(function () {
        $scope.message = "Timeout called!";        
        // AngularJS unaware of update to $scope
    }, 2000);
}

    message在内部匿名函数内被赋值,是无法触发angular的脏值检测的,正确的做法就是:

function Ctrl($scope) {
  $scope.message = "Waiting 2000ms for update";    
    setTimeout(function () {
        $scope.$apply(function () {
            $scope.message = "Timeout called!";
        });
    }, 2000);
}

如何正确使用$apply()?

$scope.$apply()接收一个函数或Angular表达式字符串,并执行它,然后调用 $scope.$digest()来更新所有绑定或侦听者。

但有些人的做法是像我最初一样,直接使用

if(!$scope.$$phase) { 
    //$digest or $apply
}

这个做法就会导致如果你的代码出错,然后又没有相应的处理机制那么程序就会卡死在那里。

$apply不仅仅执行你的代码,它内部的try / catch语句让你的错误总是能被捕捉到,并且$digist是最后的保障,它意为着即使一个错误抛出,它仍能运行。所以正确的做法是:

$scope.$apply(function () {
    $scope.message = "Timeout called!";
});

以上是我观点,如有错误,请指证!

参看文章:AngularJS and scope.$apply

© 著作权归作者所有

共有 人打赏支持
随风所欲
粉丝 2
博文 9
码字总数 7237
作品 0
成都
Angularjs的$apply及其优化使用

今天,我们要聊得是Angularjs中的小明星$apply。当我们数据更新了,但是view层却没反应时,总能听到有人说,用apply吧,然后,懵懂无知的我们,在赋值代码后面加了$scope.$apply(),然后就惊喜...

北辰狼月
07/01
0
0
再谈angularJS数据绑定机制及背后原理—angularJS常见问题总结

Angular 的数据绑定采用什么机制,详述原理? 脏检查机制。阐释脏检查机制,必须先了解如下问题。 单向绑定(ng-bind) 和 双向绑定(ng-model) 的区别? ng-bind 单向数据绑定($scope ->...

634117608
04/19
0
0
【前端】—聊聊我认识的Angular

前言 最近接触的项目前端用到了Angular框架,之前略有耳闻,从vue换到Angular,感觉东西差不多,还是要系统学习的,先来了解下。 正文 1、Angular 的发展 AngularJS 是一款来自Google的前端J...

zt15732625878
05/19
0
0
我们为什么以及是如何从Angular.js 迁移到 Vue.js?

一些背景介绍 我们的应用程序(Holistics.io )是一个基于 SQL的商业智能(BI)平台,使用Rails、Sidekiq、PostgreSQL和AngularJS编写。我们的Rails应用程序始于2013年底,作为一个简单的应用...

燕儿199606
06/14
0
0
  AngularJS中serivce,factory,provider的区别

一、service引导 刚开始学习Angular的时候,经常被误解和被初学者问到的组件是 service(), factory(), 和 provide()这几个方法之间的差别。This is where we'll start the twenty-five days ...

武文海
2015/04/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

现场看路演了!

HiBlock
16分钟前
0
0
Rabbit MQ基本概念介绍

RabbitMQ介绍 • RabbitMQ是一个消息中间件,是一个很好用的消息队列框架。 • ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。Connection是RabbitMQ的s...

寰宇01
33分钟前
1
0
官方精简版Windows10:微软自己都看不过去了

微软宣布,该公司正在寻求解决方案,以减轻企业客户的Windows 10规模。该公司声称,企业客户下载整个Windows 10文件以更新设备既费钱又费时。 微软宣布,该公司正在寻求解决方案,以减轻企业...

linux-tao
37分钟前
0
0
TypeScript基础入门之JSX(二)

转发 TypeScript基础入门之JSX(二) 属性类型检查 键入检查属性的第一步是确定元素属性类型。 内在元素和基于价值的元素之间略有不同。 对于内部元素,它是JSX.IntrinsicElements上的属性类型...

durban
今天
1
0
AVA中CAS-ABA的问题解决方案AtomicStampedReference

了解CAS(Compare-And-Swap) CAS即对比交换,它在保证数据原子性的前提下尽可能的减少了锁的使用,很多编程语言或者系统实现上都大量的使用了CAS。 JAVA中CAS的实现 JAVA中的cas主要使用的是...

码代码的小司机
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部