Я хочу предварить вопрос, говоря, что я уже прочитал и понял другие потенциально дублирующиеся вопросы (например, этот) и не смогли выполнить эту работу, что заставило меня поверить, что проблема немного отличается по своей природе, или я неправильно понял что-нибудь.
Контекст: у меня есть родительский компонент с двумя дочерними компонентами (боковое меню и основное представление). В боковом меню есть несколько фильтров в виде флажков, привязанных к объекту через [(ngModel)]
и инициирующих событие с помощью (ngModelChange)="changeFilter()"
в шаблоне.
В родительском компоненте ловлю событие: (filter)="updateFilters($event)"
. Эта функция изменяет общедоступную переменную фильтра, которую я затем передаю другому дочернему компоненту, например: [filterObject]="filters"
В компоненте основного представления я передаю переменную filterObject в канал, чтобы отфильтровать массив объектов.
Проблема: канал вызывается только один раз, после того как я впервые изменил фильтр. Переменная filterObject внутри основного представления отображается правильно обновленной, когда отображается вот так {{filterObject | json}}
, но установщик никогда не вызывается. Журналы консоли, помещенные в сеттер и геттер, показывают, что доступ получает только геттер (2-4)
Решения, которые я пробовал:
Добавление дополнительного параметра в канал для его запуска. Проблема с этим подходом заключается в том, что установка новой даты должна быть выполнена из установщика для
filterObject
, который не вызывается - как указано выше.Сделать канал нечистым (работает, но не очень хорошее решение, так как заставляет обрабатывать очень большие массивы сложных объектов 2-4 раза за клик)
Заставить родителя обновить переменную фильтра не через оператор присваивания, а через
Object.assign
, чтобы изменить ссылку и потенциально вызвать установщик
Решения, которые я рассматриваю: Если мне не удастся выяснить, в чем проблема, я подумываю о создании службы для связи между двумя компонентами через наблюдателей. В противном случае мне, возможно, придется согласиться на нечистый канал с некоторым встроенным обнаружением изменений (я думаю о преобразовании объекта фильтра в строку JSON и проверке длины).
боковое меню-component.html
<input type="checkbox" id="filter-type-2" name="filter-type-2" [(ngModel)]="filterObject.type.me" (ngModelChange)="changeFilter()">
боковое меню-component.ts
@Output() filter = new EventEmitter();
public filterObject = {
type: {
mo: true,
me: true,
ar: true,
cto: true,
gl: true,
dl: true
},
status: {
unreviewed: true,
approved: true,
other: true
}
};
// ...
changeFilter() {
this.filter.emit(this.filterObject);
}
родительский-компонент.html
<aside>
<app-article-view-aside [article]="article" (close)="closeModal($event)" (filter)="updateFilters($event)"></app-article-view-aside>
</aside>
<div class="articleContainerMainView">
<app-article-view-main [article]="article" [filterObject]="filters"></app-article-view-main>
</div>
родительский-component.ts
updateFilters(newFilter) {
this.filters = newFilter;
}
main-view-component.html
<app-finding
*ngFor="let finding of findings | findingsFilter:filterDate:filterObject; let i = index"
[finding]="finding"></app-finding>
main-view-component.ts
@Input() set filterObject(filterObject) {
console.log('setter');
this._filterObject = filterObject;
this.filterDate = Date.now();
}
get filterObject() {
console.log('getter');
return this._filterObject;
}
private _filterObject = {};
public filterDate = Date.now();
вывод в консоль при первом отображении страницы:
setter
getter
getter
getter
getter
Я действительно хочу сделать это «Угловой путь», поэтому мой вопрос к вам: что мне здесь не хватает?