Angular 4-реактивные формы-выберите элемент в списке из объекта, не указанного в этом списке - проблема trackby?
я преобразую угловой код 1.6 в угловой 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.уровни. Но соответствие между элементами моего списка и моим уровнем объекта выполняется благодаря trackby. Поэтому, когда загружается мой уровень объекта, элемент выбирается в списке.
теперь я пытаюсь преобразовать этот код, используя Реактивные Формы. В моем 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;
}
но поведение другое. Когда я устанавливаю значение элемента управления с помощью уровня объекта, элемент с тем же идентификатором в списке не выбирается.
Я нашел решение но я не понимаю, почему это не работает. Мой обходной путь-написать этот код в HTML-код:
<option *ngFor="let level of referentiel.levels;trackBy:identify" [ngValue]="level.id">{{level.label }}</option>
и в моем файле машинописного текста:
(<FormControl>this.myForm.controls.levelControl).setValue(this.level.id);
Итак, теперь он работает: мой элемент выбран в списке.
Я не понимаю разницы между двумя версиями Angular в этом случае. Может, я что-то пропустил...
Спасибо за помощь.
1 ответов
Я не вижу, что вам понадобится 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>
to
<option value="">Select</option>
так что угловой не пытается сравнить с null
значение. Это вызовет ошибку.