feat(select): add compareWith Input for object value comparison (#11965)

fixes #6625
This commit is contained in:
Zachary Keeton
2017-06-15 14:12:56 -04:00
committed by Manu MA
parent 2743c63537
commit c7645ee59d
3 changed files with 85 additions and 1 deletions

View File

@@ -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) {