Я создаю расширение Chrome с Angular для рендеринга всплывающего окна. Привязка к представлению не обновляется, когда обратный вызов поступает из Chrome API, а свойство, используемое в привязке к представлению, изменяется в результате этого обратного вызова. Добавляя дополнительные сложности, обратный вызов не вызывается напрямую, а оборачивается в Observable.
Если я позвоню ChangeDetectorRef.detectChanges()
, то представление обновляется соответствующим образом. Я попытался использовать 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);
}
};
});
});
}
}