【问题标题】:Required Field validator not working Angular 7 Reactive form必填字段验证器不起作用Angular 7反应形式
【发布时间】:2019-08-17 10:48:48
【问题描述】:

我尝试实现FormArray 控件的WebsiteUrl 字段所需的验证器。在初始表单加载时,我可以看到 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


    【解决方案1】:

    使用FormGroup.get(CONTROL) 返回一个FormControl 实例,您可以使用它来访问特定值并检查每个控件 例如FormControl.hasErrorFormControl.touched 试试下面的代码:

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

    还将Validators.required 包含在初始websiteGroup 中应该修复按钮未被禁用

     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]
                });
            });
    

    【讨论】:

    • 在实现此无法读取未定义的属性'get'后出现以下错误
    • 发生错误是因为我在按钮标记中设置了 item.get('WebsiteUrl').hasError('required') && item.get('WebsiteUrl').touched" 和 item那里不可用
    猜你喜欢
    • 2011-05-03
    • 1970-01-01
    • 2013-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多