@angular/elements 如何在 rest 调用结束时更新我的自定义元素?
@angular/elements how can I update my custom element at the end of a rest call?
所以我有了这个简单的组件:
import {
Component,
ViewEncapsulation,
OnInit,
} from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject } from 'rxjs';
@Component({
selector: 'custom-element',
template: '<div>{{ chuckText$ | async }}</div>',
styleUrls: ['./button.component.css'],
encapsulation: ViewEncapsulation.Native
})
export class ButtonComponent implements OnInit {
public chuckText$ = new BehaviorSubject<string>('');
public constructor(
private http: HttpClient
) {
this.chuckText$.next('Default Text');
}
ngOnInit() {
// nothing too fancy, just for testing purpose
this.http.get('https://api.chucknorris.io/jokes/random')
.subscribe((data: any) => {
console.log(data.value);
this.chuckText$.next(data.value);
});
}
}
构建我的组件并将其添加到一个简单的 angularJS 应用程序后,(我需要向旧应用程序添加一个自定义元素)我得到了带有默认文本和 http.get 的元素结果在控制台,但是我的组件没有更新,如图。
我显然遗漏了一些对我来说不明显的东西。关于为什么内容不更新的任何想法?
提醒一下,此功能已发布但处于实验状态,也许就是这样。
作为参考,这是我的 app.module.ts:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';
import { HttpClientModule } from '@angular/common/http';
import { ButtonComponent } from './button/button.component';
@NgModule({
declarations: [ButtonComponent],
imports: [BrowserModule, HttpClientModule],
entryComponents: [ButtonComponent],
})
export class AppModule {
constructor(private injector: Injector) {
const customElement = createCustomElement(ButtonComponent, { injector });
customElements.define('custom-button', customElement);
}
ngDoBootstrap() { }
}
我的一些客户元素遇到了同样的问题。不知何故,change detection
在客户元素中的行为与在常规 angular 应用程序中的行为不同,并且不会相应地更新视图。
解决方案 1
如果您要更新组件的状态,请手动调用 changeDetection
。
在组件的构造函数中注入 ChangeDetectorRef
并在每次您想更新视图时调用 markForCheck()
或 detectChanges()
。
注意 detectChanges()
。它将启动 changeDetection 进程,如果您未正确使用它,可能会出现性能问题。
解决方案 2
在组件中注入NgZone
并调用NgZone.run()
.
例如:
this.ngZone.run(() => this.chuckText$.next(data.value))
所以我有了这个简单的组件:
import {
Component,
ViewEncapsulation,
OnInit,
} from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject } from 'rxjs';
@Component({
selector: 'custom-element',
template: '<div>{{ chuckText$ | async }}</div>',
styleUrls: ['./button.component.css'],
encapsulation: ViewEncapsulation.Native
})
export class ButtonComponent implements OnInit {
public chuckText$ = new BehaviorSubject<string>('');
public constructor(
private http: HttpClient
) {
this.chuckText$.next('Default Text');
}
ngOnInit() {
// nothing too fancy, just for testing purpose
this.http.get('https://api.chucknorris.io/jokes/random')
.subscribe((data: any) => {
console.log(data.value);
this.chuckText$.next(data.value);
});
}
}
构建我的组件并将其添加到一个简单的 angularJS 应用程序后,(我需要向旧应用程序添加一个自定义元素)我得到了带有默认文本和 http.get 的元素结果在控制台,但是我的组件没有更新,如图。
我显然遗漏了一些对我来说不明显的东西。关于为什么内容不更新的任何想法? 提醒一下,此功能已发布但处于实验状态,也许就是这样。
作为参考,这是我的 app.module.ts:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';
import { HttpClientModule } from '@angular/common/http';
import { ButtonComponent } from './button/button.component';
@NgModule({
declarations: [ButtonComponent],
imports: [BrowserModule, HttpClientModule],
entryComponents: [ButtonComponent],
})
export class AppModule {
constructor(private injector: Injector) {
const customElement = createCustomElement(ButtonComponent, { injector });
customElements.define('custom-button', customElement);
}
ngDoBootstrap() { }
}
我的一些客户元素遇到了同样的问题。不知何故,change detection
在客户元素中的行为与在常规 angular 应用程序中的行为不同,并且不会相应地更新视图。
解决方案 1
如果您要更新组件的状态,请手动调用 changeDetection
。
在组件的构造函数中注入 ChangeDetectorRef
并在每次您想更新视图时调用 markForCheck()
或 detectChanges()
。
注意 detectChanges()
。它将启动 changeDetection 进程,如果您未正确使用它,可能会出现性能问题。
解决方案 2
在组件中注入NgZone
并调用NgZone.run()
.
例如:
this.ngZone.run(() => this.chuckText$.next(data.value))