Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 动态创建一个<;mat错误>;组件,并将其投影到父级<;垫形式字段>;组件正确_Angular_Angular Material_Angular Reactive Forms - Fatal编程技术网

Angular 动态创建一个<;mat错误>;组件,并将其投影到父级<;垫形式字段>;组件正确

Angular 动态创建一个<;mat错误>;组件,并将其投影到父级<;垫形式字段>;组件正确,angular,angular-material,angular-reactive-forms,Angular,Angular Material,Angular Reactive Forms,使用ComponentFactoryResolver动态创建组件是很简单的,但是当我尝试对中的角度材质组件执行此操作时,它似乎不会将创建的组件投影到父级。我一直在将Netanel Basal与引导组件一起使用,这对于生成表单控制错误非常有效,但由于使用了的Angle Material中使用的内容投影,我似乎无法将其用于Angle Material v8.2.1 是否可以在中动态创建并使其内容项目正常运行?我以前尝试过此方法-通过ContentChildren拾取MatErrors。由于是内容投影

使用
ComponentFactoryResolver
动态创建组件是很简单的,但是当我尝试对
中的角度材质
组件执行此操作时,它似乎不会将创建的组件投影到父级。我一直在将Netanel Basal与引导组件一起使用,这对于生成表单控制错误非常有效,但由于使用了
的Angle Material中使用的内容投影,我似乎无法将其用于Angle Material v8.2.1

是否可以在
中动态创建
并使其内容项目正常运行?

我以前尝试过此方法-通过
ContentChildren
拾取
MatError
s。由于是内容投影,动态添加或删除元素(如
materor
)不起作用——内容模板的编译和处理方式与其他模板不同

您在评论中提到,您正在尝试处理跨模板的一致错误消息……为什么不向
元素添加一个
指令
,该元素根据父控件的表单验证状态控制错误消息传递

但是,如果您希望控制模板,则不能使用指令。但是,您可以创建组件并将其用作指令:

@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.';
      // ..... 
    }
  }
@组件({
选择器:“[matErrorMessages]”,
模板:“{error}}”
})
导出类MatErrorMessagesDirective在ViewInit之后实现{
公共错误=“”;
私有输入:MatFormFieldControl;
构造函数(私有_inj:Injector){}
公共ngAfterViewInit(){
//获取对MatFormField指令的引用,其中可以访问表单控件。
让container=this.\u inj.get(MatFormField);
this.inputRef=容器。\u控件;
//sub到控件的状态流
this.inputRef.ngControl.statusChanges.subscribe(this.updateErrors);
}
私有更新错误=(状态:“有效”|“无效”)=>{
如果(状态==‘无效’){
//窗体控件上的活动错误
让controlErrors=this.inputRef.ngControl.errors;
//只要抓住一个错误
const firstError=Object.keys(controlErrors)[0];
如果(firstError===‘必需’)
this.error='此字段是必需的';
if(firstError==='minlength')
this.error='此字段应更长';
if(firstError===“来自我自己的自定义验证器的错误”)
this.error='你明白了';
// ..... 
}
}
然后在模板中

<mat-error matErrorMessages></mat-error>

通过这种方式,您可以让
MatFormField
控制
materor
的存在,就像它应该做的那样,但是您可以以一种本地化的、干净的方式控制error元素的内容

针对上述问题的突击行动:

您必须深入挖掘材质组件的私有成员,这是一种值得怀疑的做法,可以通过库更新来中断,但它是有效的


事实上,我有一个针对此类错误消息的repo,它是为@angular/material的更旧版本编写的,但我也能够掌握
验证器本身,以获得更好的错误消息,并将该验证器的整个自定义验证器/错误列表注入到模块中:

这只是另一个备选方案tive解决方案的灵感来自于为控件的句柄验证错误消息创建一个组件,它只需要是formGroup主体中的子级,并传递表单控件的名称,而不限于角材质组件

@组件({
选择器:“错误摘要”,
templateUrl:“./error summary.component.html”,
样式URL:['./错误摘要.component.css']
})
导出类ErrorSummaryComponent{
@Input()控件:字符串;
@Input()可见:任意;
构造函数(私有controlContainer:controlContainer){}
获取表单():FormGroup{
将此.controlContainer.control作为FormGroup返回;
}
get-formControl():AbstractControl{
将this.form.get(this.control)作为AbstractControl返回;
}
get isNotValid(){
返回this.formControl.invalid&(this.formControl.toucted | | this.formControl.dirty)
}
}
模板


这是必需的
这不是有效的电子邮件格式
最大值。。。
敏。。。
可以这样使用吗


...

演示中有一些代码我们可以查看…?为什么需要这样做?一个
mat表单字段
只需要有一个
mat错误
-动态更改错误内容很简单。发布stackblitz和您使用的@angular/material版本会很有帮助…
MatFormField
ges@G.Tranter我们不想将
mat error
添加到每个表单字段,因为它可以根据需要动态生成。我们完全可以使用
mat error
然后应用一个方法
{{getError('formGroup.formControl')}
,并查找错误消息,但我们会将该方法添加到每个组件中,它只会添加模板膨胀@mt@mtpultz如果您有那么多表单字段,并且计算错误的规则在它们之间是一致的,那么您可以根据处理错误句柄的
mat form field
创建自己的组件ng.因此,如果我对
mat error
使用指令,我是否能够访问
FormControl
来确定错误?我希望避免执行类似
{{getErrorMessage('formControlName')}的操作
并且非常乐意为每个组件添加
,因为这样可以避免在每个组件中添加
getError
方法。我有点认为这可能是不可能的,因为内容投影esp在尝试了它之后,但希望我错了,但该指令将是一个很好的选择。是的