Angular $rootScope:inprog 问题探究
TL;DR这是一个关于 场景和问题这几天在写一个 service 。这个 service 中有个状态需要注入到 directive 中做页面展现。因为状态的改变由另一个插件控制,不在 Angular 的 event loop 中。为了触发 dirty-checking 我在 service 中调用了 service 代码大概如下所示: const STATUS = { A: 'A',B: 'B',} class SomeService { constructor($rootScope) { this.$rootScope = $rootScope } start() { this.plugin = initPlugin // Register plugin callbacks this.plugin.onStateA = () => { this._setStatus(STATUS.A) } this.plugin.onStateB = () => { this._setStatus(STATUS.B) } } _setStatus(status) { this.status = status this.$rootScope.$digest() } } angular.module('app.someMod').service('someService',SomeService) 目前为止一切正常,直到因为需求改动,需要加一个状态,这个状态的改变是通过 directive 中的按钮触发的,于是我在 service 中加了一个方法,在 directive 中调用,代码如下: // In service class someService { connect() { this._setStatus(STATUS.C) } } // In directive,the "btnClick" is bound to an element's ng-click scope.btnClick = () => { someService.connect() } 然后一点击按钮,程序就跪了…… 控制台中报的错误是 $rootScope:inprog 。 解决方法这段错误的官方描述如下:
简单来说, 这让我反思为什么要手动调用 修改后的代码如下: // In service start() { // Wrap code in $apply this.plugin.onStateA = () => { this._wrapStatusChange(STATUS.A) } this.plugin.onStateB = () => { this._wrapStatusChange(STATUS.B) } } connect() { // Change status directly this.status = STATUS.C } _wrapStatusChange(status) { this.$rootScope.$apply(() => { this.status = status }) } 总结只在必要的时候使用 参考资料$rootScope:inprog $rootScope.ScopeScope 的 API ,里面可以查到 $digest 和 $apply 的详细解释。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |