我正在使用免费主题 Matero 开发解决方案 Angular 16 Material。
我从可下载的演示开始,所以 Angular Core ^16.2.7 等(https://github.com/ng-matero/ng-matero/blob/main/package.json),删除了无用的演示部分。
我在 http 调用后遇到订阅问题,我需要声明
@Component({
...
changeDetection: ChangeDetectionStrategy.OnPush,
})
在构造函数中
export class LoginComponent {
isSubmitting = false;
...
constructor(
...
private ref: ChangeDetectorRef,
) {}
最后在通话后例如登录
this.isSubmitting = true;
this.auth
.login(this.username.value, this.password.value, this.rememberMe.value)
.pipe(filter(authenticated => authenticated))
.subscribe({
next: () => {
this.isSubmitting = false;
this.ref.markForCheck();
},
在 html 中例如一个按钮
<button class="w-full m-y-16" mat-raised-button color="primary"
[loading]="isSubmitting"
(click)="login()">{{'login' | translate}}</button>
使用前面的代码,实际上应该不会发生任何事情(没有路由器重定向),但是通过单击按钮,按钮内的微调器应该停止旋转并返回“登录”文本。
但是发生这种情况是因为“this.ref.markForCheck();”否则,如果没有这个调用,它会忽略 isSubmitting 的更改,并且微调器保留在这里。
对于绑定到 mtx-grid 的 http 调用(返回 Observable 的 HttpClient 的正常调用)也是如此,只有通过调用“this.ref.markForCheck();”才能成功绑定。在“订阅”中。
Angular CLI 是 10.2.16
我做错了什么?
这是 OnPush
的
文档。
OnPush 更改检测指示 Angular 仅在以下情况下对组件子树运行更改检测:
- 子树的根组件接收新输入作为模板绑定的结果。 Angular 使用 ==
比较输入的当前值和过去值- Angular 会处理子树的根组件或其任何子组件中的事件(例如使用事件绑定、输出绑定或 @HostListener ),无论它们是否使用 OnPush 更改检测。
由于在您的场景中,这两种场景都不符合运行更改检测的条件,因此您需要执行
markForCheck
或 detectChanges
来触发更改检测以获得所需的输出!
您可以删除
OnPush
更改检测,也可以在需要时触发 markForCheck
。
OnPush 比普通变更检测策略更有效,因为变更检测运行较少,但您需要处理需要运行变更检测的所有情况,通常在大型 FE 负载组件上完成,以提高性能!