首页 > 解决方案 > 无法使用带有共享组件的 formControl 绑定默认值

问题描述

我有一个自定义下拉列表,我需要在其中使用 formControlName 更新或设置默认值。我在共享组件中使用 ControlValueAccessors,以便我可以在父组件中将 formControls 附加到它们并更新表单的 formControl 值。

现在我在使用以下代码设置默认值时遇到问题。

this.parentForm = this.fb.group({
  district: ['bangalore', Validators.required], // bangalore should be set as my default value.
  distance: [''],
  state:['']
});

HTML 代码:

<form [formGroup]="parentForm">
<app-common-dropdown placeHolder="select district" [dropDownId]="'districtLabel'" [dataList]="['bangalore','chennai','pune']" formControlName="district" ></app-common-dropdown>
<app-common-dropdown placeHolder="select distance" [dropDownId]="'distanceLabel'" [dataList]="[100,200,300,400]" formControlName="distance" ></app-common-dropdown>
<app-common-dropdown placeHolder="select state" [dropDownId]="'stateLabel'" [dataList]="['karnataka','tamil nadu','mumbai']" formControlName="state"  ></app-common-dropdown>

我已附上此https://stackblitz.com/edit/angular-p2gvtm的示例代码。请查看演示代码并帮助我,因为我觉得编写代码更多是为了使用表单控件设置和获取值。

标签: javascriptangulartypescriptangular-reactive-formsangular4-forms

解决方案


你好,这里是一个堆栈闪电战,它对你的代码进行了重构。

首先,如果要显示控件的值,则必须将其传递到要对其进行可视化的位置。

app.component

<form [formGroup]="parentForm">
	<app-common-dropdown [controlForDisplay]="parentForm.get('city')"
                       placeHolder="select district"
	                     [dataList]="['bangalore','chennai','pune']"></app-common-dropdown>
	<app-common-dropdown [controlForDisplay]="parentForm.get('state')" 
                       placeHolder="select distance"
	                     [dataList]="[100,200,300,400]"></app-common-dropdown>
	<app-common-dropdown [controlForDisplay]="parentForm.get('country')" 
                       placeHolder="select state"
	                     [dataList]="['karnataka','tamil nadu','mumbai']"></app-common-dropdown>
</form>

<button type="submit" (click)="getFormValues()">submit</button>

在您的情况下,我已将新输入添加到您的app-common-dropdown中,调用controlForDisplay它是为了将所需的引用传递formControl给组件。我还删除了dropdownId,我将在后面解释该操作的原因。

common-dropdown.component.html

<div [ngClass]="{'cs-active': dropdownOpen}" 
     class="cs-select cs-skin-border" 
      tabindex="0">
	<span  (click)="selectClicked($event)" class="cs-placeholder">
    {{!!controlForDisplay.value ? controlForDisplay.value : placeHolder  }} 
  </span>
  <div class="cs-options">
    <ul>
      <li *ngFor="let item of dataList" (click)="selectOption(item)">
        <span>{{item}}</span></li>
    </ul>
  </div>
</div>

所以现在我们正在前往common-dropdown.component.html,其中重要的部分是以下行 {{!!controlForDisplay.value ? controlForDisplay.value : placeHolder }}

现在通过添加的controlForDisplay输入,我们可以访问包含formControl所需下拉列表默认值的引用,并在有任何默认值时将其可视化,如果表单控件为空,则显示占位符。

commpon-dropdown.component.ts

@Component({
  selector: 'app-common-dropdown',
  templateUrl: './common-dropdown.component.html',
  styleUrls: ['./common-dropdown.component.css']
})
export class CommonDropdownComponent {

  @Input() placeHolder: string;
  @Input() dataList: any;
  @Input() controlForDisplay: FormControl = new FormControl()

  dropdownOpen = false;

  selectClicked(event: any) {
    this.dropdownOpen = true
  }

  selectOption(value: string) {
    this.controlForDisplay.patchValue(value)
    this.closeDropDown('')
  }

  closeDropDown(event: any) {
    this.dropdownOpen = false;
  }
}

这里的主要变化是,我们不是使用原生元素,而是通过 formControl API 更新 formControl 值,称为补丁值,通过这样做,我们更新了从父组件和当前组件访问的整个表单。

ps

您必须CommonModule在 app.module 中添加。

几乎可以解决您的问题。请记住,使用 Angular 创建网页时使用 Angular API-s 而不是 DOM API-s 几乎总是更可取,我建议您参加Tour of Heroes,这是官方的 Angular 教程。


推荐阅读