Chrome扩展中Angular 4绑定变更无法自动刷新的问题咨询
解决Angular 4中Chrome书签API回调不触发变更检测的问题
这问题我之前开发Chrome扩展时也踩过坑!核心原因很简单:Chrome的书签API回调函数是运行在Angular的NgZone之外的,Angular的自动变更检测机制没法捕捉到这个异步操作带来的数据变化,所以即使你把tree赋值了,视图也不会更新。
而你测试用的按钮点击能正常刷新,是因为Angular会自动把DOM事件(比如click)的处理逻辑包裹在NgZone内部,所以操作tree数组时,变更检测会被自动触发,视图也就跟着更新了。
下面给你两种靠谱的解决方案:
方案1:手动触发变更检测
通过注入ChangeDetectorRef,在回调函数里手动通知Angular检测数据变化:
import { Component, ChangeDetectorRef } from '@angular/core'; @Component({ selector: 'app-bookmarks-list', templateUrl: './bookmarkslist.component.html' }) export class BookmarksListComponent { tree: any[] = []; constructor(private cdr: ChangeDetectorRef) { chrome.bookmarks.getTree(t => { this.tree = t; // 手动触发当前组件及其子组件的变更检测 this.cdr.detectChanges(); // 如果你的组件用了OnPush变更检测策略,改用markForCheck()更合适 // this.cdr.markForCheck(); }); } addItem() { this.tree.push({ title: '测试书签', url: 'https://example.com' }); } }
方案2:将回调包裹在NgZone内
把Chrome API的回调逻辑放到NgZone.run()方法里,让整个回调运行在Angular的Zone上下文内,这样Angular就能自动跟踪数据变化并触发变更检测:
import { Component, NgZone } from '@angular/core'; @Component({ selector: 'app-bookmarks-list', templateUrl: './bookmarkslist.component.html' }) export class BookmarksListComponent { tree: any[] = []; constructor(private zone: NgZone) { chrome.bookmarks.getTree(t => { this.zone.run(() => { this.tree = t; // 这里不需要手动触发变更检测,NgZone会自动处理 }); }); } addItem() { this.tree.push({ title: '测试书签', url: 'https://example.com' }); } }
两种方案都能解决你的问题,个人更推荐方案2,因为它让第三方异步操作完全融入Angular的变更检测体系,后续如果回调里还有其他异步操作,也能自动触发检测,不用每次都手动调用变更检测方法。
内容的提问来源于stack exchange,提问作者Ala'a .H
相关产品推荐
相关产品推荐

