背景
在我正在从事的项目中,我有一个通用的集合过滤管道,...好...过滤集合。在“材料设计自动完成”控件中最常用。
<input name="someValue"
#someValueField="ngModel"
[(ngModel)]="someValue"
[matAutocomplete]="someValueAutocomplete" />
<mat-autocomplete #someValueAutocomplete="matAutocomplete">
<mat-option *ngFor="let item of collection | filterCollection:{mode: 'contains', property: 'name', value: someValue}"
[value]="item.id">
{{ item.name }}
</mat-option>
</mat-autocomplete>
问题
我想将上面示例第5行中出现的对象重构为悬挂在组件之外的对象,如下所示:
// import statements
@Component(
selector: 'app-my-awesome-component',
templateUrl: './my-awesome.component.html',
styleUrls: ['./my-awesome.component.scss']
)
export class MyAwesomeComponent implements OnInit {
public someValue: string = '';
public collection: {id: number, name: string}[] = [];
// This is what I'd like to send to the pipe...
public filteringCondition = {
mode: 'contains',
property: 'name',
value: this.someValue
};
public constructor() {}
public onInit(): void {
// Pull collection items from the database; irrelevant implementation to question.
}
// Methods and stuff are similarly irrelevant.
}
...这会使我的标记看起来像这样:
<input name="someValue"
#someValueField="ngModel"
[(ngModel)]="someValue"
[matAutocomplete]="someValueAutocomplete" />
<mat-autocomplete #someValueAutocomplete="matAutocomplete">
<!-- Refactor is below! "filterCollection"'s parameter should now be the filteringCondition object from the component... -->
<mat-option *ngFor="let item of collection | filterCollection:filteringCondition"
[value]="item.id">
{{ item.name }}
</mat-option>
</mat-autocomplete>
如果如背景示例所示将自动完成功能设置为将对象硬编码为*ngFor
属性值,则过滤器可以正常工作。但是,当我重构代码使其看起来像紧接本段上方一样时,过滤器将停止工作。
问题
是否可以像我在重构时那样将复杂的对象传递给过滤器,还是我只能直接在*ngFor
属性中硬编码过滤条件对象?
如果可能,后续问题是:什么是正确的方法?
答案 0 :(得分:1)
问题是您仅更改filteringCondition
对象的属性,而不是对象本身。当绑定到模板中的变量时,Angular的更改检测将仅在该变量的引用发生更改时才检测到更改。换句话说,如果每次filteringCondition
更改时都创建一个新的this.someValue
对象,那么您的代码应该可以再次工作。看看this StackBlitz example。