Неожиданно обновлено значение BehavioursSubject

import { Injectable, OnDestroy } from "@angular/core"; import { BehaviorSubject } from "rxjs/BehaviorSubject";

@Injectable() export class ClinicalFilteringService implements OnDestroy {
    private filtersSource = new BehaviorSubject<any>({});
    filters = this.filtersSource.asObservable();

    private savedSearchesSource = new BehaviorSubject<any>({});
    savedSearches = this.savedSearchesSource.asObservable();

    setFilters(name, filter){
        let currentFilter = this.filtersSource.getValue();
        currentFilter[name] = filter;
        if (currentFilter[name].length === 0){
            delete currentFilter[name];
        }
        this.filtersSource.next(currentFilter);
    }

    saveSearches(filters, name){
        let currentSavedSearches = this.savedSearchesSource.getValue();
        currentSavedSearches[name] = filters;
        this.savedSearchesSource.next(currentSavedSearches);
    }

}

Я новичок в angular, у меня проблемы с BehaviourSubject. Итак, у меня есть 2 BehavioralSubject: filtersSource и savedSearchesSource. savedSearchesSource будет обновляться при событии щелчка, а filtersSource будет обновляться при событии фильтрации на графике. Проблема в том, что каждый раз, когда я вызываю setFilters setFilters для обновления filtersSource, он также обновляет значение this.savedSearchesSource.getValue(). Я не уверен, почему это происходит.

Вот компонент, который использует сервис

import { Component, OnDestroy, ChangeDetectorRef, OnInit } from '@angular/core';
import { Auth } from '../../../services/auth-service';
import { Subscription } from 'rxjs/Subscription';
import { Params, ActivatedRoute, Router } from '@angular/router';
import { SearchBarService } from '../../../services/search-bar-service';
import { GenericAutocompleteResult } from '../../../model/autocomplete-result';
import { MatSnackBar, MatSnackBarRef } from '@angular/material';
import { SnackbarDemoComponent } from '../../parts/snackbar-demo/snackbar-demo.component';
import { ClinicalFilteringService } from '../../../services/clinical-filtering.service';
import { HelperService } from '../../../services/helper.service';

const SMALL_WIDTH = 720;

@Component({
    selector: 'app-search',
    templateUrl: './search.component.html',
    styleUrls: ['./search.component.css'],
    providers: [SearchBarService]
})
export class SearchComponent implements  OnInit {
    subscriptions: Subscription[] = [];
    sbSub: Subscription = null;
    autocomplete: GenericAutocompleteResult<any>;
    error = '';
    searching = false;
    sb: MatSnackBarRef<SnackbarDemoComponent> = null;
    filters = {};
    objectKeys= Object.keys;
    private mediaMatcher: MediaQueryList = matchMedia(`(max-width: ${SMALL_WIDTH}px)`);

    constructor(public searchBarService: SearchBarService,
                public auth: Auth,
                private route: ActivatedRoute,
                private cd: ChangeDetectorRef,
                public snackBar: MatSnackBar,
                private router: Router,
                private clinicalFilteringService: ClinicalFilteringService,
                private helper: HelperService,
            ) {
        if (auth.authenticated()) {
            this.subscriptions.push(route.params.subscribe(p => this.parseParams(p)));
        }
    }
    ngOnInit(): void {
        this.clinicalFilteringService.filters.subscribe(filter => this.filters = filter)
    }

    ngOnDestroy() {
        this.subscriptions.forEach((s => s.unsubscribe()));
    }

    handleError(e: string) {
        this.error = e;
    }


    deleteFilter(name: string){
        return this.clinicalFilteringService.deleteFilter(name);
    }

    saveSearches(name){
        return this.clinicalFilteringService.saveSearches(name);
    }
}

он продолжает изменять this.filters, где он использовался в качестве параметра для функции службы. Любая помощь в решении этой проблемы будет принята с благодарностью.

Код компонента, пожалуйста

Exterminator 04.10.2018 08:25

Добро пожаловать в SO, помните, когда публикуете вопрос, включайте весь соответствующий код. Представьте, что мы пробуем ваш код, например, в stackblitz, кода, который вы представляете, недостаточно для тестирования вашего кода :)

AJT82 04.10.2018 08:26

Вы постоянно повторно излучаете один и тот же объект, который вы мутируете перед его повторным излучением. Если вы сохраните один и тот же объект в двух массивах, а затем измените этот единственный объект, тогда два массива будут содержать один и тот же измененный объект. То же самое. Также, пожалуйста, используйте типы. Прекратите использовать что-либо для всего.

JB Nizet 04.10.2018 08:32

в saveSearches(filters, name) вы передаете то же имя переменной, которое вы определили как наблюдаемое, поэтому оно противоречит, измените его на что-то другое

Exterminator 04.10.2018 08:35

@JBNizet Спасибо, думаю, в этом проблема. вы можете помочь мне с решением этой проблемы?

user3794740 04.10.2018 08:41

@Exterminator тоже не работает. Я не думаю, что фильтры в параметрах saveSearches имеют какое-либо отношение к наблюдаемой переменной, которую я создал.

user3794740 04.10.2018 08:43

Ну, только не делай этого. Создайте новый объект и испустите его при вызове setFilters () вместо изменения текущего объекта.

JB Nizet 04.10.2018 08:44

либо меняйте фильтры saveSearches() в каждом месте, либо меняйте наблюдаемое имя.

Exterminator 04.10.2018 08:45

и в функции savesearchs в компоненте вы передаете одну переменную, а на принимающей стороне вы получаете два

Exterminator 04.10.2018 08:58

@JBNizet Привет, большое спасибо !! Я просто использовал Object.assign для создания копии значения, и это работает!

user3794740 04.10.2018 09:06
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
10
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Спасибо JBNizet. Я обнаружил, что проблема в том, что я постоянно переизлучаю один и тот же объект, который я мутирую перед повторным испусканием. Мое решение - создать новый объект, содержащий значение, которое будет использоваться для .next ().

Другие вопросы по теме