gpt4 book ai didi

angular - 当组件属性在回调中更改时绑定(bind)不更新

转载 作者:行者123 更新时间:2023-12-02 17:11:36 50 4
gpt4 key购买 nike

我正在使用 Angular 创建一个 Chrome 扩展来呈现弹出窗口。当回调来自 Chrome API 并且 View 绑定(bind)中使用的属性因该回调而更改时, View 绑定(bind)不会更新。更复杂的是,回调不是直接调用的,而是包装在 Observable 中。

如果我调用 ChangeDetectorRef.detectChanges() 则 View 会相应更新。我尝试使用 NgZone,但我可能使用错误 - 如果我将其包含在创建可观察值的方法中或将其排除在创建可观察值的方法中,它不会产生任何效果。

相关组件代码

ngOnInit() {
this.port = chrome.runtime.connect({ name: 'PopupToBackground' });
// ChromeUtil is an injected service wrapping chrome API calls.
this.chromeUtil.portOnMessage$(this.port).pipe(
tap((x: string) => {
// text is the bound property
this.text = x || 'no data';
// Uncomment line below and everything works.
//this.cd.detectChanges();
})
).subscribe();
}

相关 ChromeUtil 代码

@Injectable({ providedIn: 'root' })
export class ChromeUtil {
constructor(private zone: NgZone) { }

portOnMessage$(port: chrome.runtime.Port) {
return new Observable<any>(subscriber => {
return this.zone.run(() => {
const listener = (msg: any) => subscriber.next(msg);
port.onMessage.addListener(listener);
return {
unsubscribe() {
port.onMessage.removeListener(listener);
}
};
});
});
}
}

最佳答案

onMessage 事件在 Angular 外部执行,您需要调用 zone.run() 来触发更改检测。您几乎已经完成了,但在错误的点调用 run()

portOnMessage$(port: chrome.runtime.Port) {
return new Observable<any>(subscriber => {
const listener = (msg: any) => this.zone.run(() => subscriber.next(msg));
port.onMessage.addListener(listener);
return {
unsubscribe() {
port.onMessage.removeListener(listener);
}
};
});
}

传递给 port.onMessage.addListener() 的回调在 Angular 外部执行。这个回调必须在区域内运行。

  // Uncomment line below and everything works.
//this.cd.detectChanges();

如果您的组件正在使用 OnPush 更改检测,那么您必须像调用组件的任何外部可观察值一样调用 this.cd.markForCheck() 。另一种方法是在模板中使用async管道。

关于angular - 当组件属性在回调中更改时绑定(bind)不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55938523/

50 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com