首页 > 解决方案 > 必填字段验证器不起作用Angular 7反应形式

问题描述

我试图实现控件WebsiteUrl字段所需的验证器。FormArray在初始表单加载时,我可以看到 true 的值,即form.valid打印在 UI 上。当我尝试清除控件时,表单仍然有效。我正在尝试禁用保存按钮,并在控件下方显示一个标签,突出显示该字段尚未填充。

用户界面

在此处输入图像描述

html

 <div class="form-group row">
                    <label for="inputEmail" class="col-md-2 col-form-label modal-label ">Websites</label>
                    <div class="col-md-10">
                        <div class="form-group row">
                            <div class="col-md-4">
                                <label style="background-color:#dfdfdf" for="inputEmail">Website URL</label>
                            </div>
                            <div class="col-md-3">
                                <label style="background-color:#dfdfdf" for="inputEmail">User Name</label>
                            </div>
                            <div class="col-md-3">
                                <label style="background-color:#dfdfdf" for="inputEmail">Password</label>
                            </div>
                        </div>

                    </div>
                    <div class="col-md-10 offset-md-2">
                        <div formArrayName="Websites"
                            *ngFor="let item of frmFirm.get('Websites').controls; let i = index; let last = last">
                            <div [formGroupName]="i">

                                <div class="form-group row">
                                    <div class="col-md-4">
                                        <div *ngIf="!EditMode">{{FirmDetails.Websites[i].WebsiteUrl}}</div>
                                        <input *ngIf="EditMode" formControlName="WebsiteUrl" class="form-control  form-control-sm" />
                                        {{frmFirm.valid}}
                                        <label *ngIf="EditMode && !frmFirm.valid" style="color:red" for="inputEmail">Please enter Website URL</label>
                                    </div>
                                    <div class="col-md-3">
                                        <div *ngIf="!EditMode">{{FirmDetails.Websites[i].Username}}</div>
                                        <input *ngIf="EditMode" formControlName="Username" class="form-control  form-control-sm" />
                                    </div>
                                    <div class="col-md-3">
                                        <div *ngIf="!EditMode">{{FirmDetails.Websites[i].Password}}</div>
                                        <input *ngIf="EditMode" formControlName="Password" class="form-control  form-control-sm" />
                                    </div>
                                    <div class="col-md-1" *ngIf="EditMode">
                                        <button style="color: #c45703; border-color: #c45703; padding:1px" class="fa fa-trash" (click)="removeWebsite(i)"></button>
                                    </div>

                                </div>
                            </div>
                        </div>

                    </div>
                </div>
                <div class="form-group row" *ngIf="EditMode">
                    <div class="col-md-2 offset-md-2">
                        <button class="btn-firm" type="button" (click)="addWebsite()">Add Website</button>
                    </div>
                </div>
   <div class="btn-toolbar" style="padding-top:40px;">

                <span *ngIf="EditMode"><button [disabled]="!frmFirm.valid" type="submit" class="btn btn-primary btn-view-all btn mr-3">Save</button>

                </span>

零件

      constructor(private _fb: FormBuilder, private firmService: FirmService,
                     private commonDataService: CommonDataService, private notify: NotifyService,private changeDetectorRef: ChangeDetectorRef) {

                       // this.changeDetectorRef.markForCheck();
        }

        ngOnInit() {
            this.initializeFormModel();
            this.getFirmDetails();
        }


        initializeFormModel() {
            this.frmFirm = this._fb.group({
                FirmName: [''],
                DateFounded: [''],
                Websites: this._fb.array([
                    this.createWebsite()
                ])

            });
        }


        public addWebsite(): void {
            this.Websites.push(this.createWebsite());
            this.frmFirm.setErrors({'dirty': false});
        }


        public removeWebsite(index: number): void {
            const websites = this.frmFirm.get('Websites') as FormArray;
            if (websites.length === 1)
            {
                websites.reset();
              return;
            }
            websites.removeAt(index);
            this.frmFirm.setErrors({'dirty': true});
        }


        private createWebsite(): FormGroup {
            return this._fb.group({
                WebsiteUrl: ['', Validators.required],
                Username: [''],
                Password: ['']
            });
        }

         get Websites(): FormArray {
            return <FormArray>this.frmFirm.get('Websites');
        }


     const websiteGroup = FirmDetails.Websites.map(website => {
               return this._fb.group({
                FirmWebsiteId:    [website.FirmWebsiteId],
                WebsiteUrl: [website.WebsiteUrl],
                Username:   [website.Username],
                Password:   [website.Password],
                FirmId: [website.FirmId]
                });
            });
            const wesbiteFormArray: FormArray = this._fb.array(websiteGroup);
            this.frmFirm.setControl('Websites', wesbiteFormArray);
        }

        getFirmDetails() {
              if (this.FirmId != null) {
                this.firmService.getFirmDetails(this.FirmId).subscribe((data: any) => {
                    this.FirmDetails = data;
                    this.FirmId = this.FirmDetails.FirmId;
                    this.setFormValues(this.FirmDetails);
                    this.EditMode = false;
                    this.changeDetectorRef.markForCheck();

                });
            } else {
                this.FirmDetails = {};
                this.EditMode = true;
            }
        }

标签: angular

解决方案


Using FormGroup.get(CONTROL) returns a FormControl instance you can use to access specific values and checks for every control for example FormControl.hasError and FormControl.touched Try the code below:

<label 
*ngIf="item.get('WebsiteUrl').hasError('required') && 
       item.get('WebsiteUrl').touched">Please enter Website URL
</label>

Also including Validators.required into the initial websiteGroup should fix the button not being disabled

 const websiteGroup = FirmDetails.Websites.map(website => {
           return this._fb.group({
            FirmWebsiteId:    [website.FirmWebsiteId],
            WebsiteUrl: [website.WebsiteUrl, Validators.required],
            Username:   [website.Username],
            Password:   [website.Password],
            FirmId: [website.FirmId]
            });
        });

推荐阅读