如何将组件数据对象传递到管道

时间:2019-04-03 14:26:17

标签: angular typescript angular-material pipe refactoring

背景
在我正在从事的项目中,我有一个通用的集合过滤管道,...好...过滤集合。在“材料设计自动完成”控件中最常用。

<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属性中硬编码过滤条件对象?

如果可能,后续问题是:什么是正确的方法?

1 个答案:

答案 0 :(得分:1)

问题是您仅更改filteringCondition对象的属性,而不是对象本身。当绑定到模板中的变量时,Angular的更改检测将仅在该变量的引用发生更改时才检测到更改。换句话说,如果每次filteringCondition更改时都创建一个新的this.someValue对象,那么您的代码应该可以再次工作。看看this StackBlitz example

相关问题