angular - 动态创建 <mat-error> 组件并将其正确投影到父 <mat-form-field> 组件中

标签 angular angular-material angular-reactive-forms

使用 ComponentFactoryResolver动态创建组件很简单,但是当我尝试为 Angular Material <mat-error> 执行此操作时,它似乎不会将创建的组件投影到父组件中<mat-form-field> 中的组件.我一直在使用 Netanel Basal 的 example使用 Bootstrap 组件,它非常适合生成表单控制错误,但由于 Angular Material 中使用了内容投影,<mat-error>我似乎无法让它适用于 Angular Material v8.2.1。

是否可以动态创建 <mat-error><mat-form-field>并使其内容项目正确吗?

最佳答案

我以前试过这个 - MatFormField拿起MatError通过ContentChildren .由于是内容投影,动态添加或删除元素,如 MatError不起作用——内容模板的编译和处理方式与其他模板不同。
您在评论中提到您正在尝试跨模板处理一致的错误消息...为什么不添加 directive<mat-error>根据父控件的表单验证状态控制错误消息的元素?
但是,如果您要控制模板,则不能使用指令。但是,您可以创建一个组件并像指令一样使用它:

@Component({
  selector: '[matErrorMessages]',
  template: '{{ error }}'
})
export class MatErrorMessagesDirective implements AfterViewInit {
  
  public error = '';
  private inputRef: MatFormFieldControl<MatInput>;

  constructor(private _inj: Injector) { }

  public ngAfterViewInit() {
    // grab reference to MatFormField directive, where form control is accessible.
    let container = this._inj.get(MatFormField);
    this.inputRef = container._control;

    // sub to the control's status stream
    this.inputRef.ngControl.statusChanges.subscribe(this.updateErrors);
  }


  private updateErrors = (state: 'VALID' | 'INVALID') => {
    if (state === 'INVALID') {
      // active errors on the FormControl
      let controlErrors = this.inputRef.ngControl.errors;

      // just grab one error
      const firstError = Object.keys(controlErrors)[0];
      
      if(firstError === 'required')
        this.error = 'This field is required.';
 
      if(firstError === 'minlength')
        this.error = 'This field should be longer.';

      if(firstError === 'error from my own custom validator')
        this.error = 'You get the point.';
      // ..... 
    }
  }
然后在模板中......
<mat-error matErrorMessages></mat-error>
这样,你让 MatFormField控制MatError的存在正如它应该做的那样,但是您以一种本地化、干净的方式控制错误元素的内容。
上述堆栈 Blitz :https://stackblitz.com/edit/angular-sjkfft
您必须深入研究 Material 组件的私有(private)成员,这是有问题的做法,并且可能会因库更新而中断,但它确实有效。
实际上,我有一个针对这种类型的错误消息的存储库,它是为 @angular/material 的更旧版本编写的,但我也能够获得 Validator本身以获得更好的错误消息,并将该验证器的自定义验证器/错误的完整列表注入(inject)模块:https://github.com/joh04667/material-error-messages

关于angular - 动态创建 <mat-error> 组件并将其正确投影到父 <mat-form-field> 组件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58509523/

相关文章:

javascript - 用于简单悬停的 Angular2 动画,没有任何状态变化

Angular 2 Router Guards订单

Angular 4 - 在下拉列表中找到选定的值

angular - 表格数组。找不到路径控制

如果相关表单组无效,Angular 7 和表单数组会禁用表单组的按钮,并给出未定义的错误

Angular 2.0.0-rc3 : partial route matching with routerLinkActive

javascript - 将java日期转换为 Angular 日期

javascript - Angular Material md-button 悬停颜色变化

javascript - 如何在组件初始化时显示 Angular Material 工具提示

angular - BrowserAnimationsModule 和 NoopAnimationsModule 有什么区别?