-
Notifications
You must be signed in to change notification settings - Fork 133
/
Copy pathentity-selectors$.ts
109 lines (88 loc) · 4.54 KB
/
entity-selectors$.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { Inject, Injectable } from '@angular/core';
import { createFeatureSelector, createSelector, Selector, Store } from '@ngrx/store';
import { Actions } from '@ngrx/effects';
import { Observable } from 'rxjs';
import { filter, shareReplay } from 'rxjs/operators';
import { Dictionary } from '../utils/ngrx-entity-models';
import { EntityAction } from '../actions/entity-action';
import { OP_ERROR } from '../actions/entity-op';
import { ofEntityType } from '../actions/entity-action-operators';
import { ENTITY_CACHE_SELECTOR_TOKEN, EntityCacheSelector } from './entity-cache-selector';
import { EntitySelectors } from './entity-selectors';
import { EntityCache } from '../reducers/entity-cache';
import { EntityCollection, ChangeStateMap } from '../reducers/entity-collection';
import { EntityCollectionCreator } from '../reducers/entity-collection-creator';
import { EntitySelectorsFactory } from './entity-selectors';
/**
* The selector observable functions for entity collection members.
*/
export interface EntitySelectors$<T> {
/** Name of the entity collection for these selectors$ */
readonly entityName: string;
/** Observable of the collection as a whole */
readonly collection$: Observable<EntityCollection> | Store<EntityCollection>;
/** Observable of count of entities in the cached collection. */
readonly count$: Observable<number> | Store<number>;
/** Observable of all entities in the cached collection. */
readonly entities$: Observable<T[]> | Store<T[]>;
/** Observable of actions related to this entity type. */
readonly entityActions$: Observable<EntityAction>;
/** Observable of the map of entity keys to entities */
readonly entityMap$: Observable<Dictionary<T>> | Store<Dictionary<T>>;
/** Observable of error actions related to this entity type. */
readonly errors$: Observable<EntityAction>;
/** Observable of the filter pattern applied by the entity collection's filter function */
readonly filter$: Observable<string> | Store<string>;
/** Observable of entities in the cached collection that pass the filter function */
readonly filteredEntities$: Observable<T[]> | Store<T[]>;
/** Observable of the keys of the cached collection, in the collection's native sort order */
readonly keys$: Observable<string[] | number[]> | Store<string[] | number[]>;
/** Observable true when the collection has been loaded */
readonly loaded$: Observable<boolean> | Store<boolean>;
/** Observable true when a multi-entity query command is in progress. */
readonly loading$: Observable<boolean> | Store<boolean>;
/** ChangeState (including original values) of entities with unsaved changes */
readonly changeState$: Observable<ChangeStateMap<T>> | Store<ChangeStateMap<T>>;
}
/** Creates observable EntitySelectors$ for entity collections. */
@Injectable()
export class EntitySelectors$Factory {
/** Observable of the EntityCache */
entityCache$: Observable<EntityCache>;
/** Observable of error EntityActions (e.g. QUERY_ALL_ERROR) for all entity types */
entityActionErrors$: Observable<EntityAction>;
constructor(
private store: Store<any>,
private actions: Actions,
@Inject(ENTITY_CACHE_SELECTOR_TOKEN) private selectEntityCache: EntityCacheSelector
) {
// This service applies to the cache in ngrx/store named `cacheName`
this.entityCache$ = this.store.select(this.selectEntityCache);
this.entityActionErrors$ = actions.pipe(
filter((ea: EntityAction) => ea.payload && ea.payload.entityOp && ea.payload.entityOp.endsWith(OP_ERROR)),
shareReplay(1)
);
}
/**
* Creates an entity collection's selectors$ observables for this factory's store.
* `selectors$` are observable selectors of the cached entity collection.
* @param entityName - is also the name of the collection.
* @param selectors - selector functions for this collection.
**/
create<T, S$ extends EntitySelectors$<T> = EntitySelectors$<T>>(entityName: string, selectors?: EntitySelectors<T>): S$ {
const selectors$: { [prop: string]: any } = {
entityName
};
Object.keys(selectors).forEach(name => {
if (name.startsWith('select')) {
// strip 'select' prefix from the selector fn name and append `$`
// Ex: 'selectEntities' => 'entities$'
const name$ = name[6].toLowerCase() + name.substr(7) + '$';
selectors$[name$] = this.store.select((<any>selectors)[name]);
}
});
selectors$.entityActions$ = this.actions.pipe(ofEntityType(entityName));
selectors$.errors$ = this.entityActionErrors$.pipe(ofEntityType(entityName));
return selectors$ as S$;
}
}