Как передать объект данных компонента в канал - PullRequest
1 голос
/ 03 апреля 2019

Справочная информация
В проекте, над которым я работаю, у меня есть общий канал фильтрации коллекций, который ... ну ... фильтрует коллекции.Это наиболее заметно используется в элементах управления автозаполнением Material Design.

<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 Ответ

1 голос
/ 03 апреля 2019

Проблема в том, что вы изменяете только свойство объекта filteringCondition, а не сам объект. При привязке к переменным в шаблоне обнаружение изменений Angular будет обнаруживать изменения только в случае изменения ссылки на эту переменную. Другими словами, если вы создаете новый объект filteringCondition каждый раз, когда изменяется this.someValue, то ваш код должен снова работать. Взгляните на этот пример StackBlitz .

...