From b12b607fc8b9c120c33446c342a0d494b918b704 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Wed, 27 Nov 2019 09:57:17 +0300 Subject: [PATCH] refactor(core): add contidion change detection to permission directive --- .../lib/directives/permission.directive.ts | 52 ++++++++++++------- .../lib/tests/permission.directive.spec.ts | 21 +++++++- 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts b/npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts index 54657235c8..870e4ec144 100644 --- a/npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts +++ b/npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts @@ -8,17 +8,22 @@ import { ViewContainerRef, TemplateRef, Optional, + SimpleChanges, + OnChanges, } from '@angular/core'; import { Store } from '@ngxs/store'; import { ConfigState } from '../states'; import { takeUntilDestroy } from '../utils'; +import { Subscription } from 'rxjs'; @Directive({ selector: '[abpPermission]', }) -export class PermissionDirective implements OnInit, OnDestroy { +export class PermissionDirective implements OnInit, OnDestroy, OnChanges { @Input('abpPermission') condition: string; + subscription: Subscription; + constructor( private elRef: ElementRef, private renderer: Renderer2, @@ -27,26 +32,37 @@ export class PermissionDirective implements OnInit, OnDestroy { private vcRef: ViewContainerRef, ) {} + private check() { + if (this.subscription) { + this.subscription.unsubscribe(); + } + + this.subscription = this.store + .select(ConfigState.getGrantedPolicy(this.condition)) + .pipe(takeUntilDestroy(this)) + .subscribe(isGranted => { + if (this.templateRef && isGranted) { + this.vcRef.clear(); + this.vcRef.createEmbeddedView(this.templateRef); + } else if (this.templateRef && !isGranted) { + this.vcRef.clear(); + } else if (!isGranted && !this.templateRef) { + this.renderer.removeChild((this.elRef.nativeElement as HTMLElement).parentElement, this.elRef.nativeElement); + } + }); + } + ngOnInit() { - if (this.condition) { - this.store - .select(ConfigState.getGrantedPolicy(this.condition)) - .pipe(takeUntilDestroy(this)) - .subscribe(isGranted => { - if (this.templateRef && isGranted) { - this.vcRef.clear(); - this.vcRef.createEmbeddedView(this.templateRef); - } else if (this.templateRef && !isGranted) { - this.vcRef.clear(); - } else if (!isGranted && !this.templateRef) { - this.renderer.removeChild( - (this.elRef.nativeElement as HTMLElement).parentElement, - this.elRef.nativeElement, - ); - } - }); + if (this.templateRef && !this.condition) { + this.vcRef.createEmbeddedView(this.templateRef); } } ngOnDestroy(): void {} + + ngOnChanges({ condition }: SimpleChanges) { + if ((condition || { currentValue: null }).currentValue) { + this.check(); + } + } } diff --git a/npm/ng-packs/packages/core/src/lib/tests/permission.directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/permission.directive.spec.ts index 9dff7425a0..6d9dd3964f 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/permission.directive.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/permission.directive.spec.ts @@ -46,7 +46,10 @@ describe('PermissionDirective', () => { describe('structural', () => { beforeEach(() => { - spectator = createDirective(`
Testing Permission Directive
`); + spectator = createDirective( + '
Testing Permission Directive
', + { hostProps: { condition: '' } }, + ); directive = spectator.directive; }); @@ -55,7 +58,10 @@ describe('PermissionDirective', () => { }); it('should remove the element from DOM', () => { - expect(spectator.query('#test-element')).toBeFalsy(); + expect(spectator.query('#test-element')).toBeTruthy(); + expect(spectator.directive.subscription).toBeUndefined(); + spectator.setHostInput({ condition: 'test' }); + expect(spectator.directive.subscription).toBeTruthy(); grantedPolicy$.next(true); expect(spectator.query('#test-element')).toBeTruthy(); grantedPolicy$.next(false); @@ -64,5 +70,16 @@ describe('PermissionDirective', () => { grantedPolicy$.next(true); expect(spectator.queryAll('#test-element')).toHaveLength(1); }); + + describe('#subscription', () => { + it('should call the unsubscribe', () => { + const spy = jest.fn(() => {}); + spectator.setHostInput({ condition: 'test' }); + spectator.directive.subscription.unsubscribe = spy; + spectator.setHostInput({ condition: 'test2' }); + + expect(spy).toHaveBeenCalled(); + }); + }); }); });