Вызов .next () для субъекта Rx JS, который имеет тип массива, не уведомляет наблюдателя - PullRequest
0 голосов
/ 18 января 2020

Я создаю фильтр, в котором вы можете фильтровать по категориям, вы можете выбрать категорию, установив флажок рядом с названием категории.

Итак, у меня есть filterComponent, который содержит отфильтруйте его самостоятельно, затем filterService, которое имеет свойство category , которое является Subject<Array<ICategory>>, это свойство используется для передачи данных в productsComponent, где я подписан на свойство .

Этот лог c работал, когда я хотел передать простую строку, используя этот шаблон, но, кажется, он не работает, когда я хочу передать массив объектов.

В моем файле filters.component. html Я вызываю метод при изменении значения флажка:

<li *ngFor="let category of categories">
        <mat-checkbox (change)="addOrRemoveCategory(category)" [(ngModel)]="category.isChecked">
                {{'category.' + category.Name | translate}}
        </mat-checkbox>
</li>

Реализация метода addOrRemoveCategory выглядит следующим образом:

private addOrRemoveCategory(category: ICategory): void {
    if (!this.chosenCategories.includes(category)) {
        this.add(category);
    } else {
        this.remove(category);
    }
    this.filterService.categories.next(this.chosenCategories);
}

Поэтому, что бы ни происходило с категорией, добавляемой или удаляемой (я внутренне изменяю массив selectedCategories и вызываю .next () со значением), я вызываю .next () с обновленным массивом .

Проблема в том, что когда массив selectedCategories пуст, и я добавляю к нему sh и вызываю .next (), я правильно получаю значение в своей функции подписчика, но если это действие выполняется снова, и у меня есть массив из 2 элементов, и я вызываю .next (this.chosenCategories), мой метод подписчика не уведомляется.

Однако мой метод подписчика снова уведомляется, как только я звоню .next () с пустым массивом (поскольку я удалил все ранее выбранные категории).

Метод подписчика:

this.categoriesChangeSubscription = this.filterService.categories
            .pipe(
                debounceTime(500),
                distinctUntilChanged()
            )
            .subscribe((categories: Array<ICategory>) => {
                this.categories = categories.map(category => category.Name);
                this.loadData();
            });

Я что-то не так делаю? Должен ли я работать с массивами иначе, чем со строками?

Вывод: если мой массив, который я использую в качестве аргумента для .next (), изменится:

  • с длины 0 на 1, Меня уведомляют,
  • , если длина изменяется от 1 до 0, меня уведомляют,
  • , но если длина изменяется от 1 до 2, или 5-6, или от 8 до 7, я не уведомлено

1 Ответ

6 голосов
/ 18 января 2020

Полагаю, что DifferentUntilChanged () отфильтровывает ваш измененный массив, поскольку технически это тот же объект, что и раньше.

Вы можете решить его, клонировав массив:

this.filterService.categories.next([...this.chosenCategories]);

Подробнее решения под аналогичный вопрос .

...