angular - Chrome 上的 Angular 自动完成渲染问题
问题描述
我遇到了仅在 Chrome 上出现的问题。这涉及在 *ngFor 循环中使用 matAutocomplete 的组件。聚焦到绑定输入时不显示选项面板。为了确保它不仅与我的代码相关,我执行了一个非常简单的测试,将组件的所有代码替换为以下示例提供的代码:
import {Component, OnInit} from '@angular/core';
import {FormControl} from '@angular/forms';
import {Observable} from 'rxjs';
import {map, startWith} from 'rxjs/operators';
export interface User {
name: string;
}
/**
* @title Display value autocomplete
*/
@Component({
selector: 'autocomplete-display-example',
templateUrl: 'autocomplete-display-example.html',
styleUrls: ['autocomplete-display-example.css'],
})
export class AutocompleteDisplayExample implements OnInit {
myControl = new FormControl();
options: User[] = [
{name: 'Mary'},
{name: 'Shelley'},
{name: 'Igor'}
];
filteredOptions: Observable<User[]>;
ngOnInit() {
this.filteredOptions = this.myControl.valueChanges
.pipe(
startWith(''),
map(value => typeof value === 'string' ? value : value.name),
map(name => name ? this._filter(name) : this.options.slice())
);
}
displayFn(user?: User): string | undefined {
return user ? user.name : undefined;
}
private _filter(name: string): User[] {
const filterValue = name.toLowerCase();
return this.options.filter(option => option.name.toLowerCase().indexOf(filterValue) === 0);
}
}
和
<form class="example-form">
<mat-form-field class="example-full-width">
<input type="text" placeholder="Assignee" aria-label="Assignee" matInput [formControl]="myControl" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{option.name}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
然后,组件消费者是属于 mat-horizontal-stepper 的 mat-step 的一个步骤:
...
<mat-step label="Collège">
<autocomplete-display-example></autocomplete-display-example> (1)
<ng-container *ngFor="let item of myarray">
<autocomplete-display-example></autocomplete-display-example> (2)
</ng-container>
</mat-step>
...
第 (1) 行完美运行。但是使用(2),当聚焦到输入时,选项面板不显示。获得它的唯一方法是单击垫步标签。但无论如何,我无法选择一个选项。
此行为仅发生在 Chrome 上,而不是 Edge。
我会感谢一些帮助。
解决方案
一个非常丑陋的解决方案包括(感谢 https://www.gistia.com/improve-angular-performance-efficiency)分离变化检测器并在时间间隔内执行检测变化。
……
constructor(pCdr: ChangeDetectorRef) {}
....
//entering the step
this.pCdr.detach()
this.mCdrInterval = setInterval(() => {
this.mCdr.detectChanges();
}, 500);
....
//leaving the step
clearInterval(this.mCdrInterval);
this.mCdr.reattach();
但是,我仍然期待一个更整洁的方法......
推荐阅读
- javascript - 如何从 WebView 获取 div 的属性
- django - / Module“cart.context”处的 ImportError 未定义“cart_context”属性/类
- r - R:Ggplot2错误:美学必须是长度1或与数据相同(72):填充
- timer - 调用 'onReceive(_:perform:)' 的结果未使用
- typescript - 如何解决错误:错误:0909006C:PEM 例程:get_name:没有起始行?
- php - 如何安装特定版本的 Symfony?
- sql - 项目状态表推导SQL逻辑
- laravel - Laravel 中的 DRY 编码 7+
- eclipse - Eclipse 中的某些文件显示为灰色/没有语法着色/无法识别函数
- php - 更新 laravel 版本后出现 Api“401 - 未验证”错误