简体   繁体   English

Angular 4-反应形式-从列表中未引用的对象中选择列表中的项目-Trackby问题?

[英]Angular 4 - Reactive Forms - select item in a list from object not referenced in this list - trackby issue?

I am converting Angular 1.6 code to Angular 4 and I have an issue with a list of elements. 我将Angular 1.6代码转换为Angular 4,但是元素列表有问题。 The code in Angular 1.6 is: 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>

The object level is not referenced in my list because this list is loaded using the object referentiel.levels. 我的列表中未引用该对象级别,因为此列表是使用对象Referentiel.levels加载的。 But the matching between the elements of my list and my object Level is done thanks to trackby. 但是,由于trackby,我的列表元素和对象Level的匹配得以完成。 So when my object Level is loaded, the element is selected in the list. 因此,当我的对象级别被加载时,该元素在列表中被选中。

Now, I try to convert this code using Reactive Forms. 现在,我尝试使用反应式表单转换此代码。 In my HTML code, I have: 在我的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>

And in my component, I have in the OnInit method: 在组件中,我具有OnInit方法:

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

And the method identify is simple: 而且方法识别很简单:

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

But the comportment is different. 但是,举止却有所不同。 When I set the value of my control using my object Level, the item with the same id in the list is not selected. 当我使用对象“级别”设置控件的值时,未选择列表中具有相同ID的项目。

I found a solution but I don't understand why it is not working. 我找到了解决方案,但我不明白为什么它不起作用。 My workaround is to write this code in HTML: 我的解决方法是用HTML编写以下代码:

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

And in my typescript file: 在我的打字稿文件中:

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

So, now it is working: my item is selected in the list. 因此,现在可以正常工作:在列表中选择了我的项目。

I don't understand the difference between the two versions of Angular in this case. 在这种情况下,我不了解Angular的两个版本之间的区别。 Maybe I missed something... 也许我错过了什么...

Thanks for your help. 谢谢你的帮助。

I don't see that you would need the trackBy here, unless you want to use it. 我看不到这里不需要trackBy ,除非您要使用它。 But it has nothing to do with why your default option is not working. 但这与为什么您的默认选项不起作用无关。

Why it works with level.id is because this is a string (number ?) whereas level is an object that has no reference to your array, therefore it cannot be recognized from the list. 它与level.id一起使用的level.id是因为这是一个字符串(数字?),而level是一个没有引用您的数组的对象,因此无法从列表中识别它。

Since you are using Angular 4, we now have a new directive [compareWith] where we can compare some property from your level , for example the id . 由于您使用的是Angular 4,我们现在有了一个新的指令[compareWith] ,我们可以在其中比较您level某些属性,例如id Compare it with the array and find a match. 将其与数组比较并找到匹配项。 So what you can do is the following: 因此,您可以执行以下操作:

<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>

component: 零件:

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

Also notice that I changed 还要注意我改变了

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

to

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

so that Angular is not trying to compare to a null value. 因此Angular不会尝试与null值进行比较。 That would throw an error. 那会抛出一个错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM