I solved this problem like this.
Suppose you have a container news-list.component.ts with ngOnInit. It saves current queryParams in currentFilters and if there is not them makes simple GET request else it makes POST request.
    ngOnInit() {
      this.route.queryParams.subscribe(queryParams => {
        if (!!queryParams) {
          this.currentFilters = <NewsFilter>{...queryParams, offset: 0, size: 6};
          this.news$ = this.newsPostsService.getNewsByFilter(this.currentFilters);
        } else {
          this.news$ = this.newsPostsService.getMainNews();
        }
      });
    }
Then you create an component <news-rubric></news-rubric> which has following view. You pass there currentFilters and take rubricClick which you process next.
news-list.component.html
    <ml-news-rubrics [currentFilters]="currentFilters"
                     (rubricClicked)="onRubricFilter($event)"
    ></ml-news-rubrics>
news-list.component.ts
    onRubricFilter(filters: NewsFilter) {
      this.currentFilters = {...filters};
      this.router.navigate([], {queryParams: filters, relativeTo: this.route});
    }
And then inside news-rubric.component.ts you do something like this:
    onRubricClicked(rubricId: string) {
      // check if filter exists and if not then put ID in filter
      if (!this.currentFilters.filterByAnyRubricIds) { 
        this.putIdInFilter('filterByAnyRubricIds', rubricId, this.currentFilters.filterByAnyRubricIds);
      } else {
        // check if clicked ID is not in filter. put in filter
        if (!this.currentFilters.filterByAnyRubricIds.includes(rubricId)) { 
          this.putIdInFilter('filterByAnyRubricIds', rubricId, this.currentFilters.filterByAnyRubricIds);
        } else { 
          // if ID in filter remove it from filter
          this.removeIdFromFilter('filterByAnyRubricIds', rubricId, this.currentFilters.filterByAnyRubricIds);
        }
      }
      this.rubricClicked.emit(this.currentFilters);
    }
There is most tricky code. It makes new filter by updating its key with filtered ID.
    private putIdInFilter(key: string, value: any, list: any) {
      if (!list || !(list instanceof Array)) {
        if (!list) {
          this.currentFilters = {...this.currentFilters, [key]: [value]};
        } else {
          this.currentFilters = {...this.currentFilters, [key]: [this.currentFilters[key], value]};
        }
      } else {
        this.currentFilters = {...this.currentFilters, [key]: [...this.currentFilters[key], value]};
      }
    }
    private removeIdFromFilter(key: string, value: any, list: any) {
      if (!list || !(list instanceof Array)) {
        this.currentFilters = <NewsFilter>{
          ...this.currentFilters, [key]: null
        };
        return;
      }
      const filteredValues = [...list.filter(i => i !== value)];
      if (filteredValues.length > 0) {
        this.currentFilters = <NewsFilter>{
          ...this.currentFilters, [key]: filteredValues
        };
      } else {
        delete this.currentFilters[key];
      }
    }
And NewsFilter it is merely interface like QueryParams with keys which are required to be filtered.