仅在第二次点击提交时获得结果

问题描述

我正在尝试在 angular 7 中更改密码功能

在后端,如果当前密码不正确,则返回true。

并且在角度侧会出现错误消息。

但问题是我必须单击两次才能显示错误消息,即使我可以在打印真实值的日志中看到响应,但不确定为什么 *ngIf 不起作用

模板面

    <span *ngIf="hasError">
         wrong current password value  
    </span>

我的组件端

hasError: boolean;

 submit () {
     this.apiService
    .changePassword(this.formGroup.value).subscribe(res => {
  console.log(res);
  this.hasError = res;    });

服务端

  changePassword(body: any){
     return this.http.post<any>(this.url + 'changePassword',body);
  }

有人可以解释为什么我必须单击提交按钮两次才能显示 html 元素

谢谢

解决方法

我怀疑您在组件装饰器中传递了 changeDetection: ChangeDetectionStrategy.OnPush。在这种情况下,直到下一个更改检测周期(在您的情况下发生在第二次点击时)之前,angular 才会读取更改。

为了解决这个问题,您需要在构造函数中注入 ChangeDetectorRef 并手动调用更改检测周期。类似的东西:

  constructor(private cdr: ChangeDetectorRef) {}
  
  hasError: boolean;

  submit () {
     this.apiService
    .changePassword(this.formGroup.value)
    .subscribe(res => {
       console.log(res);
       this.hasError = res;    
       this.cdr.markForCheck();  // <<<---- detect changes
  });

虽然使用 ChangeDetectorRef 没有坏处,但解决此问题的另一种方法是使用 observables 和 angular async 管道。

  hasError$: new Subject();

  submit () {
    this.apiService
    .changePassword(this.formGroup.value)
    .subscribe(res => this.hasError$.next(res));

在模板中:

  <span *ngIf="hasError$ | async">
       wrong current password value  
  </span>
,

这就是您的问题的原因

hasError: boolean;

您正在初始化变量,但在开始时没有给出任何值。所以一旦组件被加载,hasError 的值就是 undefined/null。因此它只会加载具有该值的模板。

如何防止这种情况:

方法 1)(不推荐)

// If you dont want to initiate the value in the component.ts file,make this change in 
  the HTML file,<span *ngIf="!!hasError">
         wrong current password value  
</span>


the '!!' will check for null status of the variable 

方法 2) 首选

// Initiate the value of the variable to false,// In component.ts file

hasError: boolean = false; // IMPORTANT

and then your code remains the same. 

So the initial value will now be false,and also when the service is subscribed,you can have it true or false and your HTML also remains the same.