web-dev-qa-db-ja.com

Angular 4-リアクティブフォーム-このリストで参照されていないオブジェクトからリスト内のアイテムを選択-トラックバイの問題?

Angular 1.6コードをAngular 4に変換していますが、要素のリストに問題があります。Angular = 1.6は:

<select ng-model="$ctrl.level" ng-options="item as item.label for item in $ctrl.referentiel.levels | orderBy : 'index' track by item.id"                                   id="childLevel" name="childLevel" class="size-xl"                               >
<option value="">Select</option>
</select>

このリストはオブジェクトreferentiel.levelsを使用してロードされるため、リスト内のオブジェクトレベルは参照されません。しかし、リストの要素とオブジェクトのレベルのマッチングは、trackbyのおかげで行われます。そのため、オブジェクトレベルがロードされると、要素がリストで選択されます。

次に、Reactive Formsを使用してこのコードを変換しようとしています。私のHTMLコードには、次のものがあります。

<select formControlName="levelControl" id="levelSelect" name="levelSelect" class="size-xl">
<option [ngValue]="null">Select</option>
<option *ngFor="let level of referentiel.levels;trackBy:identify" [ngValue]="level">{{level.label }}</option>
</select>

そして、私のコンポーネントには、OnInitメソッドがあります。

(<FormControl>this.myForm.controls.levelControl).setValue(this.level);

そして、メソッドの識別は簡単です:

identify(index,item){
   return item.id;
}

しかし、その割合は異なります。オブジェクトレベルを使用してコントロールの値を設定すると、リスト内の同じIDを持つアイテムが選択されません。

私は解決策を見つけましたが、なぜそれが機能しないのか理解できません。私の回避策は、HTMLでこのコードを書くことです:

<option *ngFor="let level of referentiel.levels;trackBy:identify" [ngValue]="level.id">{{level.label }}</option>

そして、私のTypeScriptファイルで:

(<FormControl>this.myForm.controls.levelControl).setValue(this.level.id);

だから、今では働いています:リストで私のアイテムが選択されています。

この場合、Angularの2つのバージョンの違いを理解できません。何かを見逃したかもしれません...

ご協力いただきありがとうございます。

7
Adrien

trackByが必要なのは、それを使用する場合を除き、わかりません。ただし、デフォルトオプションが機能しない理由とは関係ありません。

level.idで機能する理由は、これが文字列(数値?)であるのに対し、levelは配列への参照を持たないオブジェクトであるため、リストから認識できないためです。

Angular 4)を使用しているため、新しいディレクティブ[compareWith]があり、levelの一部のプロパティを比較できます。たとえば、id。配列と比較して一致するものを見つけるため、次のようにします。

<select formControlName="levelControl" [compareWith]="compare" 
  id="levelSelect" name="levelSelect" class="size-xl">
    <option value="">Select</option>
    <option *ngFor="let level of referentiel.levels" [ngValue]="level">
      {{level.label }}
    </option>
</select>

成分:

compare(val1, val2) {
  return val1.id === val2.id;
}

また、私が変更したことに注意してください

<option [ngValue]="null">Select</option>

<option value="">Select</option>

そのため、Angularはnull値と比較しようとしません。エラーがスローされます。

28
AJT82