angularJS中$scope.apply()的作用——什么时候手动调用$scope.apply()

每个接触angualrJS的前端工程师都会遇到这样一个问题,为什么model数据改变了,但是view也就是页面上却没有变化,比如发现设置了颜色,可是颜色没有变,设置了值改变,可是也没变,但是console.log()能看到数据已经改变了。

然后其他人就会说那就加上$scope.apply()吧,然后你就会很神奇地发现,页面上按照想要的样子改变了。

那么$scope.apply()究竟是做了什么?

angularJS通过watcher去监听model的变化,当监听到model数据改变时,就会触发$watcher去更新页面上视图的变化。

而$scope.apply()是调用了$digest(),就是angualrJS的脏检查(就是检测变化,变化了就脏了,和之前不同了。)

怎样正确调用$scope.apply()?

观察下面两个函数,上面的函数是普通的function,下面的是$scope的function,而上面的函数不能触发脏检查(angualrJS没有办法检测到值的变化),这是因为这个函数是在angularJS的监听范围之外的,所以没有去改变view。

    function getMeterType() {
        meterService.getMeterSubTypes(function (data) {
            $scope.meterType = data;
            if ($scope.meterType) {
              $('.meterDevice a').eq(0).addClass("active");
            }
        })
    }

    $scope.changeMeterType = function (id, index) {
        $('.meterDevice a').eq(index).addClass("active").siblings().removeClass("active");
    }

这个时候就需要我们告诉angularJS,你需要做脏检查,需要更新页面的数据和样式了。

加上$scope.$apply()之后,就是告诉angularJS去检查变化的方式,就会触发$digest(),angular就会去检测变化,更新视图了。

 function getMeterType() {
        meterService.getMeterSubTypes(function (data) {
            $scope.meterType = data;
            if ($scope.meterType) {
                $timeout(function () {
                    $('.meterDevice a').eq(0).addClass("active");
                    $scope.$apply();
                });
            }
        })
    }

为什么要调用$timeout()?

如果你调用apply的时候$digest正在执行,就会看到这样的报错。

$digest already in progress

而$timeout会隐性出发digest的执行,而且会延迟执行,会在上一个digest循环完成后的下一刻,触发digest,就可以完美避开上图的报错了。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值