Angular Material 使用数组自动完成<Object>
Angular Material Autocomplete Using An Array<Object>
我有以下 Stackblitz:
AutoComplete - StackBlitz
一旦用户select选择了一个选项,然后清除输入并开始输入,过滤将停止工作。
用户如何 select 一个选项并开始在只有有效结果显示的地方输入?
它停止工作,因为您在 rxjs 流中遇到错误。
value
可以是 string
或 option
对象。您必须通过 map
运算符正确映射它:
而不是
.pipe(
startWith(''),
map(value => this._filter(value))
);
尝试以下操作:
.pipe(
startWith(''),
map(value => typeof value === 'string' ? value : value.address),
map(address => address ? this._filter(address) : this.options.slice())
);
另请参阅 显示值自动完成 Angular material docs
中的示例
更新
OP 认为这个实现有问题:
I forked off yours again and added a button just for ease. If you
select an option, click continue, backspace the "0" from the zip code,
click continue, add the zero back to the input, click continue. This
gives you undefined https://stackblitz.com/edit/angular-material-autocomplete-eg-4w15ki?file=app/autocomplete-filter-example.html
但是如果你查看 material 文档,它会按预期工作,因为在 Angular material 自动完成 Angular material 中没有 select 匹配或强制 selection 功能 https://github.com/angular/components/issues/3334
这意味着如果您输入的字符串与自动完成中的值完全匹配,那么 FormControl 值仍将是字符串,而不是您预期的对象。
为了强制执行它,您可以创建一个简单的指令,例如:
@Directive({
selector: "[forceSelection]"
})
export class AutocompleteForceSelectionDirective implements AfterViewInit, OnDestroy {
@Input() matAutocomplete: MatAutocomplete;
@Input('forceSelection') key: string;
private destroyed$ = new Subject();
constructor(
@Host() @Self() private autoCompleteTrigger: MatAutocompleteTrigger,
private ngControl: NgControl
) {}
ngAfterViewInit() {
this.autoCompleteTrigger.panelClosingActions
.pipe(
filter(e => !e || !e.source),
takeUntil(this.destroyed$)
)
.subscribe(e => {
const selected = this.matAutocomplete.options
.map(option => option.value)
.find(option => (this.key ? option[this.key] : option) === this.ngControl.value);
if (selected) {
this.ngControl.control.setValue(selected);
}
});
}
ngOnDestroy() {
this.destroyed$.next();
}
}
并将其应用于您的输入
<input ... [matAutocomplete]="auto" forceSelection="address">
我有以下 Stackblitz: AutoComplete - StackBlitz
一旦用户select选择了一个选项,然后清除输入并开始输入,过滤将停止工作。
用户如何 select 一个选项并开始在只有有效结果显示的地方输入?
它停止工作,因为您在 rxjs 流中遇到错误。
value
可以是 string
或 option
对象。您必须通过 map
运算符正确映射它:
而不是
.pipe(
startWith(''),
map(value => this._filter(value))
);
尝试以下操作:
.pipe(
startWith(''),
map(value => typeof value === 'string' ? value : value.address),
map(address => address ? this._filter(address) : this.options.slice())
);
另请参阅 显示值自动完成 Angular material docs
中的示例更新
OP 认为这个实现有问题:
I forked off yours again and added a button just for ease. If you select an option, click continue, backspace the "0" from the zip code, click continue, add the zero back to the input, click continue. This gives you undefined https://stackblitz.com/edit/angular-material-autocomplete-eg-4w15ki?file=app/autocomplete-filter-example.html
但是如果你查看 material 文档,它会按预期工作,因为在 Angular material 自动完成 Angular material 中没有 select 匹配或强制 selection 功能 https://github.com/angular/components/issues/3334
这意味着如果您输入的字符串与自动完成中的值完全匹配,那么 FormControl 值仍将是字符串,而不是您预期的对象。
为了强制执行它,您可以创建一个简单的指令,例如:
@Directive({
selector: "[forceSelection]"
})
export class AutocompleteForceSelectionDirective implements AfterViewInit, OnDestroy {
@Input() matAutocomplete: MatAutocomplete;
@Input('forceSelection') key: string;
private destroyed$ = new Subject();
constructor(
@Host() @Self() private autoCompleteTrigger: MatAutocompleteTrigger,
private ngControl: NgControl
) {}
ngAfterViewInit() {
this.autoCompleteTrigger.panelClosingActions
.pipe(
filter(e => !e || !e.source),
takeUntil(this.destroyed$)
)
.subscribe(e => {
const selected = this.matAutocomplete.options
.map(option => option.value)
.find(option => (this.key ? option[this.key] : option) === this.ngControl.value);
if (selected) {
this.ngControl.control.setValue(selected);
}
});
}
ngOnDestroy() {
this.destroyed$.next();
}
}
并将其应用于您的输入
<input ... [matAutocomplete]="auto" forceSelection="address">