fix multiples subscribes

This commit is contained in:
Dan Percic 2021-10-07 19:34:39 +03:00
parent adf27211dd
commit feaaa5d8dc
6 changed files with 47 additions and 34 deletions

View File

@ -33,9 +33,9 @@
<ng-container *ngTemplateOutlet="filterHeader"></ng-container> <ng-container *ngTemplateOutlet="filterHeader"></ng-container>
<div class="filter-content"> <div *ngIf="primaryFilters$ | async as filters" class="filter-content">
<ng-container <ng-container
*ngFor="let filter of primaryFilters$ | async" *ngFor="let filter of filters"
[ngTemplateOutletContext]="{ [ngTemplateOutletContext]="{
filter: filter, filter: filter,
filterTemplate: primaryGroup.filterTemplate, filterTemplate: primaryGroup.filterTemplate,

View File

@ -1,8 +1,10 @@
<div <ng-container *ngIf="quickFilters$ | async as filters">
(click)="filterService.toggleFilter('quickFilters', filter.id)" <div
*ngFor="let filter of quickFilters$ | async" (click)="filterService.toggleFilter('quickFilters', filter.id)"
[class.active]="filter.checked" *ngFor="let filter of filters"
class="quick-filter" [class.active]="filter.checked"
> class="quick-filter"
{{ filter.label }} >
</div> {{ filter.label }}
</div>
</ng-container>

View File

@ -1,6 +1,6 @@
import { Directive, Injector, OnDestroy, TemplateRef, ViewChild } from '@angular/core'; import { Directive, Injector, OnDestroy, TemplateRef, ViewChild } from '@angular/core';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { distinctUntilChanged, map, switchMap } from 'rxjs/operators'; import { distinctUntilChanged, map, shareReplay, switchMap } from 'rxjs/operators';
import { FilterService } from '../filtering'; import { FilterService } from '../filtering';
import { SortingService } from '../sorting'; import { SortingService } from '../sorting';
import { AutoUnsubscribe } from '../utils'; import { AutoUnsubscribe } from '../utils';
@ -54,6 +54,7 @@ export abstract class ListingComponent<T extends IListable> extends AutoUnsubscr
private get _noMatch$(): Observable<boolean> { private get _noMatch$(): Observable<boolean> {
return combineLatest([this.entitiesService.allLength$, this.listingService.displayedLength$]).pipe( return combineLatest([this.entitiesService.allLength$, this.listingService.displayedLength$]).pipe(
map(([hasEntities, hasDisplayedEntities]) => !!hasEntities && !hasDisplayedEntities), map(([hasEntities, hasDisplayedEntities]) => !!hasEntities && !hasDisplayedEntities),
shareReplay(),
distinctUntilChanged(), distinctUntilChanged(),
); );
} }
@ -61,6 +62,7 @@ export abstract class ListingComponent<T extends IListable> extends AutoUnsubscr
private get _noContent$(): Observable<boolean> { private get _noContent$(): Observable<boolean> {
return combineLatest([this._noMatch$, this.entitiesService.noData$]).pipe( return combineLatest([this._noMatch$, this.entitiesService.noData$]).pipe(
map(([noMatch, noData]) => noMatch || noData), map(([noMatch, noData]) => noMatch || noData),
shareReplay(),
distinctUntilChanged(), distinctUntilChanged(),
); );
} }

View File

@ -1,6 +1,6 @@
import { Inject, Injectable, InjectionToken, Injector, Optional } from '@angular/core'; import { Inject, Injectable, InjectionToken, Injector, Optional } from '@angular/core';
import { BehaviorSubject, Observable, Subject } from 'rxjs'; import { BehaviorSubject, Observable, Subject } from 'rxjs';
import { distinctUntilChanged, map, tap } from 'rxjs/operators'; import { distinctUntilChanged, map, shareReplay, tap } from 'rxjs/operators';
import { IListable } from '../models'; import { IListable } from '../models';
import { GenericService } from '../../services'; import { GenericService } from '../../services';
import { getLength } from '../../utils'; import { getLength } from '../../utils';
@ -30,8 +30,8 @@ export class EntitiesService<E extends IListable, I = E> extends GenericService<
@Optional() @Inject(ENTITY_PATH) protected readonly _defaultModelPath = '', @Optional() @Inject(ENTITY_PATH) protected readonly _defaultModelPath = '',
) { ) {
super(_injector, _defaultModelPath); super(_injector, _defaultModelPath);
this.all$ = this._all$.asObservable(); this.all$ = this._all$.asObservable().pipe(distinctUntilChanged(), shareReplay(1));
this.allLength$ = this._all$.pipe(getLength); this.allLength$ = this._all$.pipe(getLength, distinctUntilChanged(), shareReplay(1));
this.noData$ = this._noData$; this.noData$ = this._noData$;
} }
@ -43,6 +43,7 @@ export class EntitiesService<E extends IListable, I = E> extends GenericService<
return this.allLength$.pipe( return this.allLength$.pipe(
map(length => length === 0), map(length => length === 0),
distinctUntilChanged(), distinctUntilChanged(),
shareReplay(1),
); );
} }

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { distinctUntilChanged, map, tap } from 'rxjs/operators'; import { distinctUntilChanged, map, shareReplay, tap } from 'rxjs/operators';
import { FilterService, getFilteredEntities } from '../../filtering'; import { FilterService, getFilteredEntities } from '../../filtering';
import { SearchService } from '../../search'; import { SearchService } from '../../search';
import { IListable } from '../models'; import { IListable } from '../models';
@ -25,12 +25,15 @@ export class ListingService<E extends IListable> {
private readonly _searchService: SearchService<E>, private readonly _searchService: SearchService<E>,
private readonly _entitiesService: EntitiesService<E>, private readonly _entitiesService: EntitiesService<E>,
) { ) {
this.displayed$ = this._getDisplayed$; this.displayed$ = this._getDisplayed$.pipe(shareReplay(1));
this.displayedLength$ = this.displayed$.pipe(getLength); this.displayedLength$ = this.displayed$.pipe(getLength, distinctUntilChanged(), shareReplay(1));
this.selected$ = this._selected$.asObservable(); this.selected$ = this._selected$.asObservable().pipe(shareReplay(1));
this.selectedEntities$ = this._selected$.asObservable().pipe(map(() => this.selected)); this.selectedEntities$ = this._selected$.asObservable().pipe(
this.selectedLength$ = this._selected$.pipe(getLength); map(() => this.selected),
shareReplay(1),
);
this.selectedLength$ = this._selected$.pipe(getLength, distinctUntilChanged(), shareReplay(1));
this.areAllSelected$ = this._areAllSelected$; this.areAllSelected$ = this._areAllSelected$;
this.areSomeSelected$ = this._areSomeSelected$; this.areSomeSelected$ = this._areSomeSelected$;
@ -59,6 +62,7 @@ export class ListingService<E extends IListable> {
return combineLatest([this.displayedLength$, this.selectedLength$]).pipe( return combineLatest([this.displayedLength$, this.selectedLength$]).pipe(
map(([displayedLength, selectedLength]) => !!displayedLength && displayedLength === selectedLength), map(([displayedLength, selectedLength]) => !!displayedLength && displayedLength === selectedLength),
distinctUntilChanged(), distinctUntilChanged(),
shareReplay(),
); );
} }
@ -66,6 +70,7 @@ export class ListingService<E extends IListable> {
return this.selectedLength$.pipe( return this.selectedLength$.pipe(
map(length => !!length), map(length => !!length),
distinctUntilChanged(), distinctUntilChanged(),
shareReplay(),
); );
} }
@ -73,6 +78,7 @@ export class ListingService<E extends IListable> {
return combineLatest([this.areAllSelected$, this.areSomeSelected$]).pipe( return combineLatest([this.areAllSelected$, this.areSomeSelected$]).pipe(
map(([allAreSelected, someAreSelected]) => !allAreSelected && someAreSelected), map(([allAreSelected, someAreSelected]) => !allAreSelected && someAreSelected),
distinctUntilChanged(), distinctUntilChanged(),
shareReplay(),
); );
} }

View File

@ -23,21 +23,23 @@
<iqser-empty-state *ngIf="listingComponent.noMatch$ | async" [text]="noMatchText"></iqser-empty-state> <iqser-empty-state *ngIf="listingComponent.noMatch$ | async" [text]="noMatchText"></iqser-empty-state>
<cdk-virtual-scroll-viewport [class.no-data]="listingComponent.noContent$ | async" [itemSize]="itemSize" iqserHasScrollbar> <cdk-virtual-scroll-viewport [class.no-data]="listingComponent.noContent$ | async" [itemSize]="itemSize" iqserHasScrollbar>
<div <ng-container *ngIf="listingComponent.sortedDisplayedEntities$ | async as entities">
(mouseenter)="itemMouseEnterFn && itemMouseEnterFn(entity)" <div
(mouseleave)="itemMouseLeaveFn && itemMouseLeaveFn(entity)" (mouseenter)="itemMouseEnterFn && itemMouseEnterFn(entity)"
*cdkVirtualFor="let entity of listingComponent.sortedDisplayedEntities$ | async; trackBy: trackById" (mouseleave)="itemMouseLeaveFn && itemMouseLeaveFn(entity)"
[ngClass]="getTableItemClasses(entity)" *cdkVirtualFor="let entity of entities; trackBy: trackById"
[routerLink]="entity.routerLink" [ngClass]="getTableItemClasses(entity)"
> [routerLink]="entity.routerLink"
<div (click)="listingComponent.toggleEntitySelected($event, entity)" *ngIf="selectionEnabled" class="selection-column"> >
<iqser-round-checkbox [active]="listingComponent.isSelected(entity)"></iqser-round-checkbox> <div (click)="listingComponent.toggleEntitySelected($event, entity)" *ngIf="selectionEnabled" class="selection-column">
<iqser-round-checkbox [active]="listingComponent.isSelected(entity)"></iqser-round-checkbox>
</div>
<ng-container *ngTemplateOutlet="listingComponent.tableItemTemplate; context: { entity: entity }"></ng-container>
<div class="scrollbar-placeholder"></div>
</div> </div>
</ng-container>
<ng-container *ngTemplateOutlet="listingComponent.tableItemTemplate; context: { entity: entity }"></ng-container>
<div class="scrollbar-placeholder"></div>
</div>
</cdk-virtual-scroll-viewport> </cdk-virtual-scroll-viewport>
<iqser-scroll-button *ngIf="hasScrollButton" [itemSize]="itemSize" [scrollViewport]="scrollViewport"></iqser-scroll-button> <iqser-scroll-button *ngIf="hasScrollButton" [itemSize]="itemSize" [scrollViewport]="scrollViewport"></iqser-scroll-button>