ion-select(多个)不使用 compareWith 属性 处理对象数组

ion-select (multiple) not working with array of objects using compareWith property

我面临 ion-select(数组对象)(多个 select)的问题。 页面加载时已经 select 编辑了两个项目,但是当您打开下拉菜单时,none 个项目被选中。这是重现此问题的 stackblitz link。

https://stackblitz.com/edit/ionic-angular-v5-kie1wd

我正在为我的项目使用 Ionic(5.26.0) 和 angular(8.2.14)。

<ion-item>
  <ion-label>Users(Multi)</ion-label>
  <ion-select multiple="true" [(ngModel)]="selectedMultipleEmployee" [compareWith]="compareFn"
    (ionChange)="multiChange()">
    <ion-select-option *ngFor="let user of users" [value]="user">{{user.first + ' ' + user.last}}
    </ion-select-option>
  </ion-select>
</ion-item>
compareFn(e1: User, e2: User): boolean {
    return e1 && e2 ? e1.id === e2.id : e1 === e2;
}

TL;DR

如果 e2 是一个数组并且单个元素 e1e2 中,则您的 compareWith(e1, e2) 函数必须 return true,因为示例:

// defined outside of class
const compareWith = (e1, e2) => {
    // e2 may be an array, if multiple="true"
    if (Array.isArray(e2) ) {
        return e2.indexOf(e1) !== -1;
    }
    // fallback to single element comparison
    return e1 && e2 ? e1.id === e2.id : e1 === e2;
}

class MyPage {
...
    compareFn = compareWith;
...
}

重要:另外,在class之外定义你的函数compareWith,否则它不起作用

背景

我从 Ionic3 升级到 Ionic5 后遇到了同样的问题,我调试了 ion-select 代码以查看导致此问题的原因。

这是确定是否必须选中或取消选中某个选项的函数:

const compareOptions = (currentValue, compareValue, compareWith) => {
    if (typeof compareWith === 'function') {
        return compareWith(currentValue, compareValue);
    }
    else if (typeof compareWith === 'string') {
        return currentValue[compareWith] === compareValue[compareWith];
    }
    else {
        return Array.isArray(compareValue) ? compareValue.includes(currentValue) : currentValue === compareValue;
    }
};

compareValue 是一个数组,如果未提供 compareWith,最后的 else 子句会处理这种情况。但是由于您提供了自己的 compareWith 函数,因此它必须能够检查单个项目是否属于该数组。

这是适用于我的特定案例的实际代码(按字段 code 比较项目):

const compareWith = (f1, f2) => {
  if (Array.isArray(f2)) {
    if (!f1 || !f1.code) {
      return false;
    }
    return f2.find(val => val && val.code === f1.code);
  }
  return f1 && f2 ? f1.code === f2.code : f1 === f2;
};

更新: 添加了一条注释,即 compareWith 需要在 class.

之外定义