Angular 4 - 反应式表单 - 从此列表中未引用的对象中选择列表中的项目 - trackby 问题? [英] Angular 4 - Reactive Forms - select item in a list from object not referenced in this list - trackby issue?

查看:19
本文介绍了Angular 4 - 反应式表单 - 从此列表中未引用的对象中选择列表中的项目 - trackby 问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将 Angular 1.6 代码转换为 Angular 4,但我遇到了元素列表问题.Angular 1.6 中的代码是:

I am converting Angular 1.6 code to Angular 4 and I have an issue with a list of elements. The code in Angular 1.6 is:

<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 加载的.但是我的列表元素和我的对象 Level 之间的匹配是通过 trackby 完成的.所以当我的对象 Level 被加载时,元素在列表中被选中.

The object level is not referenced in my list because this list is loaded using the object referentiel.levels. But the matching between the elements of my list and my object Level is done thanks to trackby. So when my object Level is loaded, the element is selected in the list.

现在,我尝试使用 Reactive Forms 转换此代码.在我的 HTML 代码中,我有:

Now, I try to convert this code using Reactive Forms. In my HTML code, I have:

<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 方法:

And in my component, I have in the OnInit method:

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

而且识别方法很简单:

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

但是行为不一样.当我使用我的对象 Level 设置我的控件的值时,列表中具有相同 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.

我找到了一个解决方案,但我不明白为什么它不起作用.我的解决方法是用 HTML 编写此代码:

I found a solution but I don't understand why it is not working. My workaround is to write this code in 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);

所以,现在它可以工作了:我的项目在列表中被选中.

So, now it is working: my item is selected in the list.

在这种情况下,我不明白两个版本的 Angular 之间的区别.也许我错过了什么......

I don't understand the difference between the two versions of Angular in this case. Maybe I missed something...

感谢您的帮助.

推荐答案

我不认为您需要 trackBy 在这里,除非您想使用它.但这与为什么您的默认选项不起作用无关.

I don't see that you would need the trackBy here, unless you want to use it. But it has nothing to do with why your default option is not working.

为什么它与 level.id 一起使用是因为这是一个字符串(数字?)而 level 是一个没有引用数组的对象,因此它不能从列表中识别.

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.

由于您使用的是 Angular 4,我们现在有一个新指令 [compareWith],我们可以在其中比较 level 的某些属性,例如 id.将其与数组进行比较并找到匹配项.因此,您可以执行以下操作:

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

组件:

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

还要注意我变了

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

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

这样 Angular 就不会尝试与 null 值进行比较.那会抛出错误.

so that Angular is not trying to compare to a null value. That would throw an error.

这篇关于Angular 4 - 反应式表单 - 从此列表中未引用的对象中选择列表中的项目 - trackby 问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆