libs/acl/src/lib/acl-tag/acl-tag.ts
Properties |
Methods |
Accessors |
constructor(tagName: BehaviorSubject
|
||||||||||||
Defined in libs/acl/src/lib/acl-tag/acl-tag.ts:28
|
||||||||||||
Parameters :
|
_aclKeySubject |
Type : ReplaySubject<AclTagItem>
|
Default value : new ReplaySubject<AclTagItem>(1)
|
Defined in libs/acl/src/lib/acl-tag/acl-tag.ts:22
|
tagName$ |
Type : BehaviorSubject<string>
|
Defined in libs/acl/src/lib/acl-tag/acl-tag.ts:20
|
transient$ |
Type : BehaviorSubject<boolean>
|
Default value : new BehaviorSubject<boolean>(false)
|
Defined in libs/acl/src/lib/acl-tag/acl-tag.ts:21
|
destroy |
destroy()
|
Defined in libs/acl/src/lib/acl-tag/acl-tag.ts:50
|
Returns :
void
|
Static joinKeys | ||||||
joinKeys(...keys: string[])
|
||||||
Defined in libs/acl/src/lib/acl-tag/acl-tag.ts:26
|
||||||
Parameters :
Returns :
any
|
notifyChildren |
notifyChildren()
|
Defined in libs/acl/src/lib/acl-tag/acl-tag.ts:75
|
Returns :
void
|
subscribeToChanges |
subscribeToChanges()
|
Defined in libs/acl/src/lib/acl-tag/acl-tag.ts:62
|
wait for parent changes or own tag name changes and calculate tag name for each change
Returns :
void
|
update |
update()
|
Defined in libs/acl/src/lib/acl-tag/acl-tag.ts:79
|
Returns :
void
|
aclKey$ |
getaclKey$()
|
Defined in libs/acl/src/lib/acl-tag/acl-tag.ts:46
|
changed$ |
getchanged$()
|
Defined in libs/acl/src/lib/acl-tag/acl-tag.ts:54
|
aclKey |
getaclKey()
|
Defined in libs/acl/src/lib/acl-tag/acl-tag.ts:90
|
ownTag |
getownTag()
|
Defined in libs/acl/src/lib/acl-tag/acl-tag.ts:97
|
isTransient |
getisTransient()
|
Defined in libs/acl/src/lib/acl-tag/acl-tag.ts:101
|
tagList |
gettagList()
|
Defined in libs/acl/src/lib/acl-tag/acl-tag.ts:105
|
parentList |
getparentList()
|
Defined in libs/acl/src/lib/acl-tag/acl-tag.ts:112
|
import { BehaviorSubject, combineLatest, ReplaySubject, Subject } from 'rxjs';
import { startWith, takeUntil, tap } from 'rxjs/operators';
/**
* Core element of our hierarchical acl tag toolkit.
* Each time we find an element with a aclTag the bound directive (AclTagDirective)
* creates an instance of this AclTag and injects it as 'ACL_TAG_TOKEN'.
*
* The created instance has a binding to the property 'aclTag' of the directive
* and to any parent AclTag which builds up the expected hierarchy.
*/
export interface AclTagItem {
ownKey: string;
parentKeys: string[];
aclKey: string /** full qualified path **/;
}
export class AclTag {
tagName$: BehaviorSubject<string>;
transient$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
_aclKeySubject: ReplaySubject<AclTagItem> = new ReplaySubject<AclTagItem>(1);
private _changed$ = new Subject<void>();
private _destroySignal$ = new Subject<void>();
static joinKeys(...keys: string[]) {
return keys.join('/');
}
constructor(
tagName: BehaviorSubject<string> | string,
private parent?: AclTag,
transient?: BehaviorSubject<boolean>
) {
if (typeof tagName === 'string') {
tagName = new BehaviorSubject(tagName);
}
if (transient) {
this.transient$ = transient;
}
this.tagName$ = tagName;
this.subscribeToChanges();
}
get aclKey$() {
return this._aclKeySubject.asObservable().pipe(takeUntil(this._destroySignal$));
}
destroy() {
this._destroySignal$.next();
}
get changed$() {
return this._changed$.asObservable();
}
/**
* wait for parent changes or own tag name changes and
* calculate tag name for each change
*/
subscribeToChanges() {
const parentList = (this.parent?.changed$ ?? new Subject<void>()).pipe(startWith([null]));
combineLatest([this.tagName$, parentList, this.transient$])
.pipe(
tap(() => {
this.update();
}),
takeUntil(this._destroySignal$)
)
.subscribe();
}
notifyChildren() {
this._changed$.next();
}
update() {
// write current acl key intro the stream
this._aclKeySubject.next({
aclKey: this.aclKey,
ownKey: this.ownTag,
parentKeys: this.parentList
});
// notify dependent acl tags
this.notifyChildren();
}
get aclKey() {
if (this.isTransient) {
return AclTag.joinKeys(...this.parentList, this.ownTag);
}
return AclTag.joinKeys(...this.tagList);
}
get ownTag() {
return this.tagName$.getValue();
}
get isTransient() {
return this.transient$.getValue();
}
get tagList(): string[] {
if (this.isTransient) {
return this.parentList;
}
return this.parentList.concat(this.ownTag);
}
get parentList() {
return [...(this.parent?.tagList ?? [])];
}
}