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

时间:2019-05-13 13:39:08

标签: javascript angular typescript angular-reactive-forms angular4-forms

我有一个自定义下拉列表,需要在其中使用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设置和获取值。

1 个答案:

答案 0 :(得分:2)

您好,这里是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值更新了formControl值,这样做是为了更新从父级和当前组件均可访问的整个窗体

p.s。

您必须在您的app.module内部添加CommonModule

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