Added search filter optimalisations

This commit is contained in:
lotte
2019-03-11 16:28:42 +01:00
parent 1738b723c1
commit db9861b495
9 changed files with 36 additions and 14 deletions

View File

@@ -8,7 +8,7 @@
</a> </a>
<ng-container *ngFor="let page of (filterValues$ | async)?.payload"> <ng-container *ngFor="let page of (filterValues$ | async)?.payload">
<div [@facetLoad]="animationState"> <div [@facetLoad]="animationState">
<ng-container *ngFor="let value of page.page; let i=index"> <ng-container *ngFor="let value of page.page; trackBy: trackUpdate">
<a *ngIf="!(selectedValues | async).includes(value.value)" class="d-flex flex-row" <a *ngIf="!(selectedValues | async).includes(value.value)" class="d-flex flex-row"
[routerLink]="[getSearchLink()]" [routerLink]="[getSearchLink()]"
[queryParams]="getAddParams(value.value) | async" queryParamsHandling="merge"> [queryParams]="getAddParams(value.value) | async" queryParamsHandling="merge">

View File

@@ -290,6 +290,14 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
getDisplayValue(facet: FacetValue, query: string): string { getDisplayValue(facet: FacetValue, query: string): string {
return new EmphasizePipe().transform(facet.value, query) + ' (' + facet.count + ')'; return new EmphasizePipe().transform(facet.value, query) + ' (' + facet.count + ')';
} }
/**
* Prevent unnecessary rerendering
*/
trackUpdate(index, value: FacetValue) {
return value ? value.search : undefined;
}
} }
export const facetLoad = trigger('facetLoad', [ export const facetLoad = trigger('facetLoad', [

View File

@@ -1,6 +1,6 @@
import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; import { combineLatest as observableCombineLatest, Observable } from 'rxjs';
import { Injectable, InjectionToken } from '@angular/core'; import { Injectable, InjectionToken } from '@angular/core';
import { map } from 'rxjs/operators'; import { distinctUntilChanged, map } from 'rxjs/operators';
import { SearchFiltersState, SearchFilterState } from './search-filter.reducer'; import { SearchFiltersState, SearchFilterState } from './search-filter.reducer';
import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store'; import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store';
import { import {
@@ -65,6 +65,8 @@ export class SearchFilterService {
return observableCombineLatest(values$, prefixValues$).pipe( return observableCombineLatest(values$, prefixValues$).pipe(
map(([values, prefixValues]) => { map(([values, prefixValues]) => {
console.log('getSelectedValuesForFilter ', values, prefixValues);
if (isNotEmpty(values)) { if (isNotEmpty(values)) {
return values; return values;
} }
@@ -88,13 +90,14 @@ export class SearchFilterService {
} else { } else {
return false; return false;
} }
}) }),
distinctUntilChanged()
); );
} }
/** /**
* Request the current page of a given filter * Request the current page of a given filter
* @param {string} filterName The filtername for which the page state is checked * @param {string} filterName The filter name for which the page state is checked
* @returns {Observable<boolean>} Emits the current page state of the given filter, if it's unavailable, return 1 * @returns {Observable<boolean>} Emits the current page state of the given filter, if it's unavailable, return 1
*/ */
getPage(filterName: string): Observable<number> { getPage(filterName: string): Observable<number> {
@@ -106,7 +109,8 @@ export class SearchFilterService {
} else { } else {
return 1; return 1;
} }
})); }),
distinctUntilChanged());
} }
/** /**

View File

@@ -8,7 +8,7 @@
</a> </a>
<ng-container *ngFor="let page of (filterValues$ | async)?.payload"> <ng-container *ngFor="let page of (filterValues$ | async)?.payload">
<div [@facetLoad]="animationState"> <div [@facetLoad]="animationState">
<ng-container *ngFor="let value of page.page; let i=index"> <ng-container *ngFor="let value of page.page; trackBy: trackUpdate">
<a *ngIf="!(selectedValues | async).includes(value.value)" class="d-flex flex-row" <a *ngIf="!(selectedValues | async).includes(value.value)" class="d-flex flex-row"
[routerLink]="[getSearchLink()]" [routerLink]="[getSearchLink()]"
[queryParams]="getAddParams(value.value) | async" queryParamsHandling="merge" > [queryParams]="getAddParams(value.value) | async" queryParamsHandling="merge" >

View File

@@ -24,7 +24,7 @@
</ng-container> </ng-container>
<ng-container *ngFor="let page of (filterValues$ | async)?.payload"> <ng-container *ngFor="let page of (filterValues$ | async)?.payload">
<div [@facetLoad]="animationState"> <div [@facetLoad]="animationState">
<ng-container *ngFor="let value of page.page; let i=index"> <ng-container *ngFor="let value of page.page; trackBy: trackUpdate">
<a *ngIf="!(selectedValues | async).includes(value.value)" class="d-flex flex-row" <a *ngIf="!(selectedValues | async).includes(value.value)" class="d-flex flex-row"
[routerLink]="[getSearchLink()]" [routerLink]="[getSearchLink()]"
[queryParams]="getChangeParams(value.value) | async" queryParamsHandling="merge"> [queryParams]="getChangeParams(value.value) | async" queryParamsHandling="merge">

View File

@@ -9,7 +9,7 @@
<ng-container *ngVar="(filterValues$ | async) as filterValuesRD"> <ng-container *ngVar="(filterValues$ | async) as filterValuesRD">
<div [@facetLoad]="animationState"> <div [@facetLoad]="animationState">
<ng-container *ngFor="let page of filterValuesRD?.payload"> <ng-container *ngFor="let page of filterValuesRD?.payload">
<ng-container *ngFor="let value of page.page; let i=index"> <ng-container *ngFor="let value of page.page; trackBy: trackUpdate">
<a *ngIf="!(selectedValues | async).includes(value.value)" class="d-flex flex-row" <a *ngIf="!(selectedValues | async).includes(value.value)" class="d-flex flex-row"
[routerLink]="[getSearchLink()]" [routerLink]="[getSearchLink()]"
[queryParams]="getAddParams(value.value) | async" queryParamsHandling="merge" > [queryParams]="getAddParams(value.value) | async" queryParamsHandling="merge" >

View File

@@ -1,6 +1,6 @@
<h3>{{"search.filters.head" | translate}}</h3> <h3>{{"search.filters.head" | translate}}</h3>
<div *ngIf="(filters | async)?.hasSucceeded"> <div *ngIf="(filters | async)?.hasSucceeded">
<div *ngFor="let filter of (filters | async)?.payload"> <div *ngFor="let filter of (filters | async)?.payload; trackBy: trackUpdate">
<ds-search-filter *ngIf="isActive(filter) | async" class="d-block mb-3 p-3" [filter]="filter"></ds-search-filter> <ds-search-filter *ngIf="isActive(filter) | async" class="d-block mb-3 p-3" [filter]="filter"></ds-search-filter>
</div> </div>
</div> </div>

View File

@@ -1,6 +1,6 @@
import { Observable, of as observableOf } from 'rxjs'; import { Observable, of as observableOf } from 'rxjs';
import { filter, map, mergeMap, startWith, switchMap } from 'rxjs/operators'; import { filter, first, map, mergeMap, startWith, switchMap, tap } from 'rxjs/operators';
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { SearchService } from '../search-service/search.service'; import { SearchService } from '../search-service/search.service';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
@@ -9,6 +9,7 @@ import { SearchConfigurationService } from '../search-service/search-configurati
import { isNotEmpty } from '../../shared/empty.util'; import { isNotEmpty } from '../../shared/empty.util';
import { SearchFilterService } from './search-filter/search-filter.service'; import { SearchFilterService } from './search-filter/search-filter.service';
import { getSucceededRemoteData } from '../../core/shared/operators'; import { getSucceededRemoteData } from '../../core/shared/operators';
import { FieldUpdate } from '../../core/data/object-updates/object-updates.reducer';
@Component({ @Component({
selector: 'ds-search-filters', selector: 'ds-search-filters',
@@ -59,11 +60,13 @@ export class SearchFiltersComponent {
*/ */
isActive(filterConfig: SearchFilterConfig): Observable<boolean> { isActive(filterConfig: SearchFilterConfig): Observable<boolean> {
return this.filterService.getSelectedValuesForFilter(filterConfig).pipe( return this.filterService.getSelectedValuesForFilter(filterConfig).pipe(
mergeMap((isActive) => { switchMap((isActive) => {
console.log('selected fires');
if (isNotEmpty(isActive)) { if (isNotEmpty(isActive)) {
return observableOf(true); return observableOf(true);
} else { } else {
return this.searchConfigService.searchOptions.pipe( return this.searchConfigService.searchOptions.pipe(
first(),
switchMap((options) => { switchMap((options) => {
return this.searchService.getFacetValuesFor(filterConfig, 1, options).pipe( return this.searchService.getFacetValuesFor(filterConfig, 1, options).pipe(
filter((RD) => !RD.isLoading), filter((RD) => !RD.isLoading),
@@ -73,6 +76,13 @@ export class SearchFiltersComponent {
} }
)) ))
} }
}),startWith(true),); }), tap(t => console.log(t)), startWith(true));
}
/**
* Prevent unnecessary rerendering
*/
trackUpdate(index, config: SearchFilterConfig) {
return config ? config.name : undefined;
} }
} }

View File

@@ -16,7 +16,7 @@ export class RouteService {
getQueryParameterValues(paramName: string): Observable<string[]> { getQueryParameterValues(paramName: string): Observable<string[]> {
return this.route.queryParamMap.pipe( return this.route.queryParamMap.pipe(
map((params) => [...params.getAll(paramName)]), map((params) => [...params.getAll(paramName)]),
distinctUntilChanged() distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b))
); );
} }