首页 > 解决方案 > 级联下拉填充方法在 Angular 7 中运行多个

问题描述

我有一个角度应用程序。我在下面的示例中使用了级联组合框(国家/地区)。但是,get states()方法在state.component.ts运行很多时间。这可能是什么原因?我只想运行更改的国家/地区选择。我把debugger. 您可以通过 F12 打开控制台来重现错误。 如果我的方法错误,我可以完全改变我的方式。

堆栈闪电战

标签: angulartypescriptangular7

解决方案


当您使用 getter 时,这会在组件的生命周期中发生几次。

你必须改变你的方法。一种方法是订阅表单的 valueChanges,并在订阅中更改“状态”。有些喜欢

export class StateComponent  {
  _studentForm;  //Use a _studentForm
  @Input() 
  set studentForm(value)  //use a setter, to subscribe when has value
  {
     this._studentForm=value;
     this._studentForm.get(this.countryId).valueChanges.subscribe(res=>{
       var val = this._studentForm.controls[this.countryId].value;
       this.states=this.selectService.filterStates(val);
     })
  }
  @Input() id:string;
  @Input() countryId:string;
  states: State[];

  constructor(private selectService: SelectService) { }
}

您的 component.html 必须引用_studentForm

<form [formGroup]="_studentForm">
    <select [formControlName]="id" >
      <option [value]="0">--Select--</option>
      <option *ngFor="let state of states " value= {{state.id}}>{{state.name}}</option>
    </select>
</form>

你的分叉堆栈闪电战

更新 好吧,考虑到整个问题,也许是时候创建一个控制国家和州的组件了。这是一些更复杂的因为我们必须使用 viewProviders 和 FormGroupDirective。

这个想法,将控件的名称(countryID 和 StateID)和控件的标签(countryLabel 和 stateLabel)作为参数传递给组件

新组件变为

@Component({
  selector: 'app-country-state',
  viewProviders: [
    {
      provide: ControlContainer,
      useExisting: FormGroupDirective
    }
  ],
  templateUrl: './country-state.component.html',
  styleUrls: ['./country-state.component.css']
})
export class CountryStateComponent implements OnInit, OnDestroy {

  @Input() countryID: string;
  @Input() stateID: string;
  @Input() countryLabel: string;
  @Input() stateLabel: string;

  _countryID: FormControl;  //We must control two "FormControl"
  _stateID: FormControl;    //One for country and one for stated
  states: any[] = [];
  countries: any[] = [];

  isAlive: boolean = true;
  constructor(private selectService: SelectService,
    private fgd: FormGroupDirective) { }

  ngOnInit() {
    //first, we get the countries
    this.countries = this.selectService.getCountries();

    //"search" the controls using the FormGroupDirective
    this._countryID = (this.fgd.form.get(this.countryID) as FormControl);
    this._stateID = (this.fgd.form.get(this.stateID) as FormControl);
    //Our subscribe to valueChanges. We use a "tipical" contruction "takeWhile"
    //To unsubscribe when the compnent are destroyed
    this._countryID.valueChanges.pipe(
      takeWhile(() => this.isAlive)
    ).subscribe(res => {
      this.states = this.selectService.filterStates(this._countryID.value);
    })

  }
  ngOnDestroy() {
    this.isAlive = false;
  }
}

.html

{{countryLabel}}:<br/>
<!--see that we use [formControl], NOT [formControlName]-->
<select [formControl]="_countryID">
      <option [value]="0">--Select--</option>
      <option *ngFor="let country of countries" [value]="country.id">{{country.name}}</option>
    </select>
    <br/>
{{stateLabel}}:<br/>
    <select [formControl]="_stateID" >
      <option [value]="0">--Select--</option>
      <option *ngFor="let state of states " value= {{state.id}}>{{state.name}}</option>
    </select>

以及使用

<app-country-state 
    [countryID]="'countryId1'" [countryLabel]="'Student Country'"
    [stateID]="'stateId1'" [stateLabel]="'Student State'">
</app-country-state>

分叉的堆栈闪电战


推荐阅读