angularJS——数据更新了但是view层却未更新问题及解决方法

Posted 林景之

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了angularJS——数据更新了但是view层却未更新问题及解决方法相关的知识,希望对你有一定的参考价值。

搬运自:https://www.cnblogs.com/yky-iris/p/9251230.html?utm_source=debugrun&utm_medium=referral

 

视图不更新问题及原因: 在原生js或者第三方框架下,修改model,是有可能不会触发视图更新的,比如setTimeout、jquery插件。因为他们脱离了Angularjs的上下文,Angularjs并不能监听到数据的改变。

解决方法:利用$apply()手动更新视图,如下。(注意这是最不推荐的解决方法)

html:

<p>{{name}}</p>

js:

$scope.name="张三";
setTimeout(function(){
    $scope.name = \'李四\';
    //$scope.$apply()
},500)

 

  一. $apply(),digest概念  

 

  $apply()函数的作用: 可以从Angular框架的外部让表达式在Angular上下文内部执行。

  $apply()函数工作原理:相当于一个触发器,它的作用就是触发digest循环,从而更新视图。

  digest是什么?:digest是Angularjs的核心,是它实现了神奇的数据绑定。凡是触发事件,必会触发digest循环,比如ng事件,click,change,实际上都是触发了digest循环。

 

 

  二. 更好的运用digest   

  在Angularjs中,除了$apply可以触发digest循环外,还有其他的方法,也可以触发此循环。而且$apply往往是最坏的选择。下面推荐一些更好的选择。

 

(1). $digest

$scope.$digest()的速度要比$apply要快,因为它只更新当前作用域和子作用域的值,对于父作用域时不管的。而$apply还要评估父作用域,这就大大消耗了性能。

(2). $timeout

用$timeout去代替你的setTimeout,$timeout作为Angularjs的自带服务,当然时更契合Angularjs环境啦。它会隐性触发digest循环,而且它会延迟执行,会在上一个digest循环完成后的下一刻,触发digest循环,这样就不会出现上文所说的   

$digest already in progress

 

我们把setTime的代码放到$timeout中,注意:需要在相应的factory或者service中引入——mianApp.controller(\'listController\', function($scope,$http,$timeout) {···})

$timeout(function(){
  $scope.name = \'李四\';
},500)

这就能正常工作了,看,没有讨厌的apply了!

(3). $evalAsync

最推荐的应该时这个方法了。如果当前正好有一个digest循环在执行,那么它就会把导致digest循环的操作,放到当前digest循环中去执行。而$timeout是要等到当前digest循环执行完,再执行一次digest循环才可以。所以evalAsync执行更快,性能更好。我们可以像$timeout那样去调用它,即

$scope.$evalAsync(
    function( $scope ) {
        console.log( "$evalAsync" );
    }
);

 

附:当http请求为异步时,数据可能无法获取,视图也就无法更新。此时将请求改为同步,或用以上更新数据的四种方法也可。

以上是关于angularJS——数据更新了但是view层却未更新问题及解决方法的主要内容,如果未能解决你的问题,请参考以下文章

angularjs 之 $watch

在 MVC VIEW 中使用 AngularJS/AJAX 呈现后端数据

AngularJS学习1-基础知识

4.AngularJS四大特征之二: 双向数据绑定

Angularjs 不会在 ng-view 中加载脚本

认识 angularjs 及 angularjs 简单实用