mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
feat(select): add compareWith Input for object value comparison (#11965)
fixes #6625
This commit is contained in:
@@ -123,6 +123,31 @@ import { SelectPopover, SelectPopoverOption } from './select-popover-component';
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* ### Object Value References
|
||||
*
|
||||
* When using objects for select values, it is possible for the identities of these objects to
|
||||
* change if they are coming from a server or database, while the selected value's identity
|
||||
* remains the same. For example, this can occur when an existing record with the desired object value
|
||||
* is loaded into the select, but the newly retrieved select options now have different identities. This will
|
||||
* result in the select appearing to have no value at all, even though the original selection in still intact.
|
||||
*
|
||||
* Using the `compareWith` `Input` is the solution to this problem
|
||||
*
|
||||
* ```html
|
||||
* <ion-item>
|
||||
* <ion-label>Employee</ion-label>
|
||||
* <ion-select [(ngModel)]="employee" [compareWith]="compareFn">
|
||||
* <ion-option *ngFor="let employee of employees" [value]="employee">{{employee.name}}</ion-option>
|
||||
* </ion-select>
|
||||
* </ion-item>
|
||||
* ```
|
||||
*
|
||||
* ```ts
|
||||
* compareFn(e1: Employee, e2: Employee): boolean {
|
||||
* return e1 && e2 ? e1.id === e2.id : e1 === e2;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @demo /docs/demos/src/select/
|
||||
*/
|
||||
@Component({
|
||||
@@ -153,6 +178,7 @@ export class Select extends BaseInput<any> implements OnDestroy {
|
||||
_overlay: ActionSheet | Alert | Popover;
|
||||
_texts: string[] = [];
|
||||
_text: string = '';
|
||||
_compareWith: (o1: any, o2: any) => boolean = isCheckedProperty;
|
||||
|
||||
/**
|
||||
* @input {string} The text to display on the cancel button. Default: `Cancel`.
|
||||
@@ -187,6 +213,18 @@ export class Select extends BaseInput<any> implements OnDestroy {
|
||||
*/
|
||||
@Input() selectedText: string = '';
|
||||
|
||||
/**
|
||||
* @input {Function} The function that will be called to compare object values
|
||||
*/
|
||||
@Input()
|
||||
set compareWith(fn: (o1: any, o2: any) => boolean) {
|
||||
if (typeof fn !== 'function') {
|
||||
throw new Error(`compareWith must be a function, but received ${JSON.stringify(fn)}`);
|
||||
}
|
||||
this._compareWith = fn;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @output {any} Emitted when the selection was cancelled.
|
||||
*/
|
||||
@@ -448,7 +486,7 @@ export class Select extends BaseInput<any> implements OnDestroy {
|
||||
this._options.forEach(option => {
|
||||
// check this option if the option's value is in the values array
|
||||
option.selected = this.getValues().some(selectValue => {
|
||||
return isCheckedProperty(selectValue, option.value);
|
||||
return this._compareWith(selectValue, option.value);
|
||||
});
|
||||
|
||||
if (option.selected) {
|
||||
|
||||
Reference in New Issue
Block a user