【问题标题】:Why is my mat-error only shown if I click two times on button?为什么我的 mat-error 只有在我单击按钮两次时才会显示?
【发布时间】:2019-04-08 17:21:55
【问题描述】:

我有一个从我的数据库中检索数据的搜索栏,只要搜索成功,检索到的数据就会填充一个 mat 表,到目前为止一切都很好并且可以正常工作。

我面临的问题是,由于用户提供了无效信息,该搜索无法从数据库中检索到任何内容。

当我向输入表单提供数据并且 HTTP 响应失败时,应该会立即触发 mat-error,但是只有在我单击搜索按钮两次时才会发生这种情况。

这是我的代码:

MyComponent.component.ts

public inputForm: FormControl;

ngOnInit() {
  this.inputForm = new FormControl('');
}

private searchForReturnByOrderNumber(value) {
  this.rest.getOrderByNumber(value).subscribe((orderNrData: {}) => {
    if (Object.entries(orderNrData).length !== 0) {
      this.rest.getReturnByOrderNumber(value).subscribe((returnOrdNrData: Return[]) => {
        if (Object.entries(returnOrdNrData).length !== 0) {
          this.returns = returnOrdNrData;
          this.setReturns();
        } else {
          this.openDialog(orderNrData, returnOrdNrData);
        }
      }, error => {
        if (error.status === 404) {
          this.openDialog(orderNrData, []);
        }
      });
    } else {
      this.inputForm.setErrors({ 'invalid': true });
    }
  }, error => {
    this.inputForm.setErrors({ 'invalid': true });
  });
}

private isInputInvalid() {
  if (this.inputForm.hasError('invalid')) {
    return true;
  }
  return false;
}

private getErrorMessage() {
  return this.inputForm.invalid ? 'Invalid Search!' : '';
}

MyComponent.component.html

<div class="row">
  <div class="col-2"></div>

  <div class="col-8 search-div">

    <mat-form-field class="search-form-field" appearance="outline">
      <mat-label>Search</mat-label>

      <input matInput class="search-input" placeholder="Ex: EU030327" [formControl]="inputForm" #searchInput>
      <mat-error *ngIf="isInputInvalid()">{{ getErrorMessage() }}</mat-error>

    </mat-form-field>

    <span matSuffix>
      <button mat-flat-button class="search-btn" color="accent" [disabled]="isInputInvalid()"
        (click)="searchForReturnByOrderNumber(searchInput.value)"><i class="fa fa-search"></i></button>
    </span>

  </div>

  <div class="col-2"></div>
</div>

如果我输入一些无效数据(数据库中不存在的数据)并按下我的“search-btn”,我的 mat 错误将不会出现,只有当我再次按下按钮时。

我已经调试过了,代码正确输入了预期的代码:

} else {
  this.inputForm.setErrors({ 'invalid': true });
}

它将 inputForm 设置为无效,但直到我再次单击该按钮才会出现 mat-error...

有谁知道可能出了什么问题?

谢谢!

【问题讨论】:

    标签: javascript node.js angular typescript


    【解决方案1】:

    您的*ngIf 的条件不会重新计算。 我认为您可以将其替换为:

    <mat-error *ngIf="inputForm?.hasError('invalid')">{{ getErrorMessage() }}</mat-error>
    

    此外,您不需要 getErrorMessage() 方法中的条件。仅当您有错误开始时才会显示该消息。 您可能有一个竞争条件导致此方法返回一个空字符串。尝试简化它。

    【讨论】:

    • 感谢您的回复!我试过了,但我仍然需要在按钮上单击两次才能显示 mat-error...
    • 你能发布你的inputForm的初始化吗?
    • 我更新了我的答案。你还能检查getErrorMessage() 方法返回的内容吗?
    • 我把它改成了这个&lt;mat-error *ngIf="inputForm?.hasError('invalid')"&gt;Invalid Search!&lt;/mat-error&gt;,但我仍然有同样的问题......我知道getErrorMessage()没有问题,因为当搜索无效时我的搜索按钮会被禁用并且只有当我点击它两次时才会发生这种情况。
    【解决方案2】:

    你的 mat-error 必须是 ngIf* 吗?不能只用ngClass吗?

    如果你有一个 isInputInvalid 属性,最初设置为 false,如果你的搜索方法返回“无效”,然后将你的 isInputInvalid 属性设置为 true,它会不起作用吗?

    那么你就可以使用 ngClass:

    <mat-error [ngClass]="{'your-class': isInputInvalid}">{{ getErrorMessage() }}</mat-error>
    

    编辑:

    HTML:

    <mat-error [ngClass="{'show-mat-error': isInputInvalid}">{{ getErrorMessage() }}</mat-error>
    

    TS - 您需要更改“isInputInvalid”属性:

    isInputInvalid: boolean = false;
    

    TS - 您需要按照这些思路实现一个方法来更改 'isInputInvalid' 的值:

    if (this.inputForm.hasError('invalid')) {
       this.isInputInvalid = true;
    } else {
      this.isInputInvalid = false;
    }
    

    CSS:

    mat-error {
    display: none;
    }
    
    .show-mat-error {
    display: block;
    }
    

    我可能还会在您的组件中执行类似的操作,以便在用户每次导航到页面时隐藏错误:

        constructor(private router: Router) {
    
      router.events.subscribe((event: Event) => {
    
        if (event instanceof NavigationStart) {
          this.isInputInvalid = false;
        }
      });
    

    我希望这会有所帮助!

    【讨论】:

    • 我使用 *ngIf 是因为我只想在我的搜索无效时显示 mat-error...我从未使用过 ngClass 绑定,我应该用什么代替 '你的班级?
    • 如果你将 mat-error 设置为 display:none,那么'your-class' 将是一个带有 'display:block' 的 CSS 类,并且当 'isInputInvalid' 设置为 true 时,CSS类将被添加到 mat-error 并且以前的 display:none 样式将设置为 display:block 并且 mat-error 将呈现。这是 angular 资源:angular.io/api/common/NgClass#description 如果您还没有使用过 ngClass 和 ngStyle,它们是值得一看的,它们很有用。希望这可以帮助!注意,'your-class' 可以是组件 CSS 模板中的任何 CSS 类,并包含所需的任何样式
    • 我不确定我的做法是否正确,因为它不起作用......我这样做了:&lt;mat-error class="hide-mat-error" [ngClass]="{'display-mat-error': inputInvalid}"&gt;Invalid Search!&lt;/mat-error&gt; 在我的 CSS 中我有以下类:.hide-mat-error{ display: none; } .display-mat-error{ display: block; } 在我的 .ts我用this.inputInvalid = true;替换了this.inputForm.setErrors({ 'invalid': true });的文件
    • 我编辑了我的答案,我希望一切都有意义并有所帮助!
    • 我试过了,但我没有运气... mat-error 不会立即显示,我仍然需要按下按钮 2 次。我在网上找不到任何关于使用 mat-error 进行 http 响应的信息
    【解决方案3】:

    我能够解决我的问题,因此我会将我的解决方案发布给任何可能遇到此问题的人...

    我创建了一个布尔值isInputInvalid 并将其默认设置为 true。每当我按下搜索按钮时,都会执行 HTTP 请求,并且根据响应,isInputInvalid 布尔值设置为 true 或 false。如果 HTTP 响应无效,我将其设置为 true,如果有效,我将其设置为 false。

    然后,如果布尔值为真,我将我的表单控件设置为无效。

    在我的 HTML 文件中,我用 &lt;form&gt; 包围了我的输入,并创建了一个 [formGroup]。对于错误验证,我将*ngIf 内的&lt;mat-error&gt; 设置为等于searchForm.controls['inputForm'].invalid

    这是我的代码:

    MyComponent.component.ts

    private searchForm: FormGroup;
    private isInputInvalid: boolean = true;
    
    ngOnInit() {
      this.searchForm = new FormGroup({
        inputForm: new FormControl('')
      });
    }
    
    private searchForReturnByOrderNumber(value) {
      this.rest.getOrderByNumber(value).subscribe((orderNrData: {}) => {
        if (Object.entries(orderNrData).length !== 0) {
          this.rest.getReturnByOrderNumber(value).subscribe((returnOrdNrData: Return[]) => {
            if (Object.entries(returnOrdNrData).length !== 0) {
              this.isInputInvalid = false;
              this.returns = returnOrdNrData;
              this.setReturns();
            } else {
              this.isInputInvalid = false;
              this.openDialog(orderNrData, returnOrdNrData);
            }
          }, error => {
            this.isInputInvalid = true;
          });
        } else {
          this.isInputInvalid = true;
        }
      }, error => {
        this.isInputInvalid = true;
      });
    
      if(this.isInputInvalid){
        this.searchForm.controls['inputForm'].setErrors({ 'invalid': true });
      }
    }
    
    private getErrorMessage() {
      return this.searchForm.controls['inputForm'].invalid ? 'Invalid Search!' : '';
    }
    

    MyComponent.component.html

    <div class="row">
      <div class="col-2"></div>
    
      <div class="col-8 search-div">
        <form [formGroup]="searchForm">
          <mat-form-field class="search-form-field" appearance="outline">
            <mat-label>Search</mat-label>
    
            <input matInput class="search-input" placeholder="Ex: EU030327" formControlName="inputForm" #searchInput>
            <mat-error *ngIf="searchForm.controls['inputForm'].invalid">{{ getErrorMessage() }}</mat-error>
    
          </mat-form-field>
        </form>
    
        <span matSuffix>
          <button mat-flat-button class="search-btn" color="accent" [disabled]="searchForm.controls['inputForm'].invalid"
            (click)="searchForReturnByOrderNumber(searchInput.value)"><i class="fa fa-search"></i></button>
        </span>
    
      </div>
    
      <div class="col-2"></div>
    </div>
    

    【讨论】:

      猜你喜欢
      • 2018-03-26
      • 2019-10-28
      • 2021-12-30
      • 2018-06-29
      • 2021-01-29
      • 2015-10-27
      • 1970-01-01
      • 1970-01-01
      • 2021-12-28
      相关资源
      最近更新 更多