Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.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 如何将验证器和CSS样式传播到自定义角度表单组件内的输入控件?_Angular_Angular7_Angular8 - Fatal编程技术网

Angular 如何将验证器和CSS样式传播到自定义角度表单组件内的输入控件?

Angular 如何将验证器和CSS样式传播到自定义角度表单组件内的输入控件?,angular,angular7,angular8,Angular,Angular7,Angular8,我有一个嵌套表单组件,该组件带有一个设置为与formControlName=“nested”一起使用的字段。验证程序在父级FormControl上设置,如下所示: form=this.fb.group({ 值:['',[Validators.required,Validators.minLength(3)], 嵌套:[''[Validators.required,Validators.minLength(3)], }); 我想将状态从父级FormControl传播到嵌套的,这样它的反应方式与常

我有一个嵌套表单组件,该组件带有一个设置为与
formControlName=“nested”
一起使用的
字段。验证程序在父级
FormControl
上设置,如下所示:

form=this.fb.group({
值:['',[Validators.required,Validators.minLength(3)],
嵌套:[''[Validators.required,Validators.minLength(3)],
});
我想将状态从父级
FormControl
传播到嵌套的
,这样它的反应方式与常规的非嵌套
的反应方式相同,即只需触摸它并单击submit(这是
control.markAsTouched()
)即可,状态设置为无效,CSS样式
ng INVALID
已设置

以下代码订阅了父控件的状态更改,我成功地获得了部分胜利,但“触摸”嵌套输入将使其恢复为有效,单击提交将不会设置
ng invalid
样式

@ViewChild('tbNgModel',{static:false})tbNgModel:NgModel;
私人生活=真实;
构造函数(@Optional()@Self()公共ngControl:ngControl,私有cdr:ChangeDetectorRef){
如果(this.ngControl!=null){
this.ngControl.valueAccessor=此;
}
}
ngAfterViewInit():void{
此文件为.ngControl.statusChanges.pipe(
takeWhile(()=>this.isAlive)
).订阅(状态=>{
log('Status changed:','Status'Errors:',this.ngControl.Errors);
this.tbNgModel.control.setErrors(this.ngControl.errors);
this.cdr.detectChanges();
});
this.ngControl.control.updateValueAndValidity();//强制发出初始值
}

如何才能真正将状态传播到嵌套控件,同时只在父控件
FormControl
上设置验证器

最终解决方案 从@Eliseo的答案来看,这是我最终完成的实现(它对我很有效,但可能还有更好的方法)

组件技术

构造函数(@Optional()@Self()public-ngControl:ngControl){
如果(this.ngControl!=null){
this.ngControl.valueAccessor=此;
}
}
...
getValidationCss(){
if(!this.ngControl)返回{};
返回{
“ng无效”:this.ngControl.invalid,
'is invalid':this.ngControl.invalid&&this.ngControl.toucted,
“ng valid”:this.ngControl.valid,
“ng toucted”:this.ngControl.toucted,
“ng未触及”:this.ngControl.untouched,
“ng pristine”:this.ngControl.pristine,
“ng dirty”:this.ngControl.dirty,
};
}
component.html

。。。
...

Dstj,事情必须更简单。见

就在我们的输入中,我们可以使用[ngClass]

<input [ngClass]="{'ng-touched':ngControl.control.touched,'ng-invalid':ngControl.control.invalid}" 
type="text" class="form-control" [(ngModel)]="value" 
       (ngModelChange)="propagateChange($event)"
       (blur)="touched()"
 > 
查看是否为有效/无效触摸/未触摸的ngControl

已更新添加(模糊)以标记为已触摸

使用ngDoCheck更新2

另一种解决方案是使用ngDoCheck

我们的组成部分

  value: string;
  customClass=null;
  onChange:boolean=false;

    constructor(@Self() public ngControl: NgControl,private el:ElementRef) {
        if (this.ngControl != null) {
            this.ngControl.valueAccessor = this;
        }
    }
  ngDoCheck()
  {
    if (!this.onChange)
    {
      this.onChange=true;
      //it's necesary a setTimeOut to give Angular a chance
      setTimeout(()=>{
        this.customClass=this.el.nativeElement.getAttribute('class');
        this.onChange=false;
      })
    }
  }
  change(value:any)
  {
    this.propagateChange(value);
    this.touched(null)
  }
html文件

<input #tbNgModel="ngModel" [ngClass]="customClass" type="text" class="form-control" 
     [(ngModel)]="value" 
     (ngModelChange)="change($event)" 
     (blur)="touched()"> 


谢谢,但如果您只是“循环”浏览(触摸而不更改任何内容),则您的示例不适用于
ng invalid
。它似乎在某个地方缺少“刷新”,因为它被设置为
ng valid
,即使
ngControl.control.invalid=true
::glups::我忘了指示何时触摸,您可以使用(blur)=“toucted()”。刚刚在stackblitz和答案中更正。是的,控件无效,但输入有效Hanks。我仍然觉得必须重新编码ng-*CSS类的应用程序,而
(blur)
事件很奇怪,但它确实起作用了…;)在进一步的测试中,它只起到了一半的作用,因为输入的底层
ngModel
中的状态仍然有效,所以我将
class=“ng VALID ng invalid”
两者结合起来。我需要将状态设置为无效,因为在我的真实应用程序中,我还有一个自定义指令,用于查找
控件。应用boostrap的
的无效状态是无效的
CSS类。如果基础的
ngModel
保持有效,则它不起作用。在考虑了这个问题之后,我决定使用DoCheck将类属性复制到输入中,请参见我更新的答案和stackblitz
<input #tbNgModel="ngModel" [ngClass]="customClass" type="text" class="form-control" 
     [(ngModel)]="value" 
     (ngModelChange)="change($event)" 
     (blur)="touched()">