无法使用带有共享组件的 formControl 绑定默认值

Unable to bind default value using formControl with shared component

我有一个自定义下拉菜单,我需要在其中使用 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 的示例代码。请查看演示代码并帮助我,因为我觉得编写的代码更多是为了使用 formcontrols 设置和获取值。

你好,这里是 stackblitz 重构代码分支。

首先,如果你想显示控件的值,你必须将它传递到你要显示它的地方。

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 值,称为补丁值,这样做我们更新整个表单,可以从父组件和当前组件。

p.s.

您必须在 app.module 中添加 CommonModule

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