UNPKG

@wizdm/teleport

Version:
84 lines 11.2 kB
import { Directive, SimpleChange, Input, Output, EventEmitter, TemplateRef, ViewContainerRef } from '@angular/core'; import { NgTemplateOutlet } from '@angular/common'; import { switchMap, delay } from 'rxjs/operators'; import { BehaviorSubject } from 'rxjs'; import { TeleportService } from './teleport.service'; export class PortalDirective extends NgTemplateOutlet { constructor(teleport, host, container) { super(container); this.teleport = teleport; this.host = host; this.name$ = new BehaviorSubject(''); this.firstChange = true; /** The actual template in use. NOTE for this event to bind correclty the directive must be used in its de-sugared form */ this.template = new EventEmitter(); /** True then the portal is active */ this.active = new EventEmitter(); /** Optional data passed along from the TeleportDirective back to the Portal */ this.data = new EventEmitter(); // Builds the template observable this.sub = this.name$.pipe( // Beams the content with the given name switchMap(name => this.teleport.beam(name)), // Wait the next round to avoid expressionChangedAfterItHasBeenChecked() exception delay(0)).subscribe(payload => this.changeTemplate(payload || {})); } /** The portal name */ set name(name) { this.name$.next(name); } changeTemplate({ template, data }) { // Emits the new optional data, if any if (typeof (data) !== undefined) { this.data.emit(data); } /** Skips on no template changes */ if (template === this.ngTemplateOutlet) { return; } // Creates a simple change object const ngTemplateOutlet = new SimpleChange(this.ngTemplateOutlet, template || this.host, this.firstChange); // Updates the parent's template variable accordingly this.ngTemplateOutlet = ngTemplateOutlet.currentValue; // Tracks for the first change this.firstChange = false; // Forces the change to occur super.ngOnChanges({ ngTemplateOutlet }); // Emits the new template this.template.emit(this.ngTemplateOutlet); // Emits true whenever the template isn't the host one this.active.emit(this.ngTemplateOutlet !== this.host); } // Intercepts the input changes ngOnChanges(changes) { // Gets rid of the name's SimpleChange object if (changes.name) { delete changes.name; } // Skips when no changes remains if (Object.keys(changes).length === 0) { return; } // Lets the context changes go through super.ngOnChanges(changes); } // Disposes of the subscription on deletion ngOnDestroy() { this.sub.unsubscribe(); } } PortalDirective.decorators = [ { type: Directive, args: [{ selector: 'ng-template[wmPortal]', exportAs: 'wmPortal' },] } ]; PortalDirective.ctorParameters = () => [ { type: TeleportService }, { type: TemplateRef }, { type: ViewContainerRef } ]; PortalDirective.propDecorators = { name: [{ type: Input, args: ['wmPortal',] }], ngTemplateOutletContext: [{ type: Input, args: ['wmPortalContext',] }], template: [{ type: Output, args: ['wmPortalTemplate',] }], active: [{ type: Output, args: ['wmPortalActive',] }], data: [{ type: Output, args: ['wmPortalData',] }] }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9ydGFsLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3RlbGVwb3J0L3NyYy9saWIvcG9ydGFsLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUF1QyxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pKLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbEQsT0FBTyxFQUFnQixlQUFlLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDckQsT0FBTyxFQUFFLGVBQWUsRUFBbUIsTUFBTSxvQkFBb0IsQ0FBQztBQU10RSxNQUFNLE9BQU8sZUFBZ0IsU0FBUSxnQkFBZ0I7SUFxQm5ELFlBQW9CLFFBQXlCLEVBQVUsSUFBOEIsRUFBRSxTQUEyQjtRQUNoSCxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7UUFEQyxhQUFRLEdBQVIsUUFBUSxDQUFpQjtRQUFVLFNBQUksR0FBSixJQUFJLENBQTBCO1FBbkI3RSxVQUFLLEdBQUcsSUFBSSxlQUFlLENBQVMsRUFBRSxDQUFDLENBQUM7UUFDeEMsZ0JBQVcsR0FBWSxJQUFJLENBQUM7UUFTcEMsMEhBQTBIO1FBQzlGLGFBQVEsR0FBRyxJQUFJLFlBQVksRUFBNEIsQ0FBQztRQUVwRixzQ0FBc0M7UUFDWixXQUFNLEdBQUcsSUFBSSxZQUFZLEVBQVcsQ0FBQztRQUUvRCwrRUFBK0U7UUFDdkQsU0FBSSxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFLckQsaUNBQWlDO1FBQ2pDLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJO1FBRXhCLHdDQUF3QztRQUN4QyxTQUFTLENBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBRTtRQUU3QyxrRkFBa0Y7UUFDbEYsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUVULENBQUMsU0FBUyxDQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLElBQUksRUFBcUIsQ0FBQyxDQUFFLENBQUM7SUFDbEYsQ0FBQztJQTVCRCxzQkFBc0I7SUFDdEIsSUFBdUIsSUFBSSxDQUFDLElBQVksSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUE2QjVELGNBQWMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQW1CO1FBRXhELHNDQUFzQztRQUN0QyxJQUFHLE9BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxTQUFTLEVBQUU7WUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUFFO1FBRXhELG1DQUFtQztRQUNuQyxJQUFHLFFBQVEsS0FBSyxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFBRSxPQUFPO1NBQUU7UUFFbEQsaUNBQWlDO1FBQ2pDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLFFBQVEsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUUxRyxxREFBcUQ7UUFDckQsSUFBSSxDQUFDLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDLFlBQVksQ0FBQztRQUV0RCw4QkFBOEI7UUFDOUIsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7UUFFekIsNkJBQTZCO1FBQzdCLEtBQUssQ0FBQyxXQUFXLENBQUMsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7UUFFeEMseUJBQXlCO1FBQ3pCLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBRTFDLHNEQUFzRDtRQUN0RCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFRCwrQkFBK0I7SUFDL0IsV0FBVyxDQUFDLE9BQXNCO1FBRWhDLDZDQUE2QztRQUM3QyxJQUFHLE9BQU8sQ0FBQyxJQUFJLEVBQUU7WUFBRSxPQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUM7U0FBRTtRQUV6QyxnQ0FBZ0M7UUFDaEMsSUFBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7WUFBRSxPQUFPO1NBQUU7UUFFakQsc0NBQXNDO1FBQ3RDLEtBQUssQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUVELDJDQUEyQztJQUMzQyxXQUFXLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUM7OztZQWpGMUMsU0FBUyxTQUFDO2dCQUNULFFBQVEsRUFBRSx1QkFBdUI7Z0JBQ2pDLFFBQVEsRUFBRSxVQUFVO2FBQ3JCOzs7WUFMUSxlQUFlO1lBSjRFLFdBQVc7WUFBRSxnQkFBZ0I7OzttQkFpQjlILEtBQUssU0FBQyxVQUFVO3NDQUdoQixLQUFLLFNBQUMsaUJBQWlCO3VCQUd2QixNQUFNLFNBQUMsa0JBQWtCO3FCQUd6QixNQUFNLFNBQUMsZ0JBQWdCO21CQUd2QixNQUFNLFNBQUMsY0FBYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgT25EZXN0cm95LCBPbkNoYW5nZXMsIFNpbXBsZUNoYW5nZXMsIFNpbXBsZUNoYW5nZSwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBUZW1wbGF0ZVJlZiwgVmlld0NvbnRhaW5lclJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTmdUZW1wbGF0ZU91dGxldCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBzd2l0Y2hNYXAsIGRlbGF5IH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uLCBCZWhhdmlvclN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFRlbGVwb3J0U2VydmljZSwgVGVsZXBvcnRQYXlsb2FkIH0gZnJvbSAnLi90ZWxlcG9ydC5zZXJ2aWNlJztcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnbmctdGVtcGxhdGVbd21Qb3J0YWxdJyxcbiAgZXhwb3J0QXM6ICd3bVBvcnRhbCdcbn0pXG5leHBvcnQgY2xhc3MgUG9ydGFsRGlyZWN0aXZlIGV4dGVuZHMgTmdUZW1wbGF0ZU91dGxldCBpbXBsZW1lbnRzIE9uRGVzdHJveSwgT25DaGFuZ2VzIHtcblxuICBwcml2YXRlIG5hbWUkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KCcnKTtcbiAgcHJpdmF0ZSBmaXJzdENoYW5nZTogYm9vbGVhbiA9IHRydWU7XG4gIHByaXZhdGUgc3ViOiBTdWJzY3JpcHRpb247XG5cbiAgLyoqIFRoZSBwb3J0YWwgbmFtZSAqL1xuICBASW5wdXQoJ3dtUG9ydGFsJykgc2V0IG5hbWUobmFtZTogc3RyaW5nKSB7IHRoaXMubmFtZSQubmV4dChuYW1lKTsgfVxuXG4gIC8qKiBUaGUgcG9ydGFsIGNvbnRleHQgKi9cbiAgQElucHV0KCd3bVBvcnRhbENvbnRleHQnKSBuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dDogT2JqZWN0fG51bGw7XG5cbiAgLyoqIFRoZSBhY3R1YWwgdGVtcGxhdGUgaW4gdXNlLiBOT1RFIGZvciB0aGlzIGV2ZW50IHRvIGJpbmQgY29ycmVjbHR5IHRoZSBkaXJlY3RpdmUgbXVzdCBiZSB1c2VkIGluIGl0cyBkZS1zdWdhcmVkIGZvcm0gKi9cbiAgQE91dHB1dCgnd21Qb3J0YWxUZW1wbGF0ZScpIHRlbXBsYXRlID0gbmV3IEV2ZW50RW1pdHRlcjxUZW1wbGF0ZVJlZjxPYmplY3R8bnVsbD4+KCk7XG5cbiAgLyoqIFRydWUgdGhlbiB0aGUgcG9ydGFsIGlzIGFjdGl2ZSAgKi9cbiAgQE91dHB1dCgnd21Qb3J0YWxBY3RpdmUnKSBhY3RpdmUgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG5cbiAgLyoqIE9wdGlvbmFsIGRhdGEgcGFzc2VkIGFsb25nIGZyb20gdGhlIFRlbGVwb3J0RGlyZWN0aXZlIGJhY2sgdG8gdGhlIFBvcnRhbCAqL1xuICBAT3V0cHV0KCd3bVBvcnRhbERhdGEnKSBkYXRhID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSB0ZWxlcG9ydDogVGVsZXBvcnRTZXJ2aWNlLCBwcml2YXRlIGhvc3Q6IFRlbXBsYXRlUmVmPE9iamVjdHxudWxsPiwgY29udGFpbmVyOiBWaWV3Q29udGFpbmVyUmVmKSB7IFxuICAgIHN1cGVyKGNvbnRhaW5lcik7IFxuXG4gICAgLy8gQnVpbGRzIHRoZSB0ZW1wbGF0ZSBvYnNlcnZhYmxlXG4gICAgdGhpcy5zdWIgPSB0aGlzLm5hbWUkLnBpcGUoIFxuXG4gICAgICAvLyBCZWFtcyB0aGUgY29udGVudCB3aXRoIHRoZSBnaXZlbiBuYW1lXG4gICAgICBzd2l0Y2hNYXAoIG5hbWUgPT4gdGhpcy50ZWxlcG9ydC5iZWFtKG5hbWUpICksXG5cbiAgICAgIC8vIFdhaXQgdGhlIG5leHQgcm91bmQgdG8gYXZvaWQgZXhwcmVzc2lvbkNoYW5nZWRBZnRlckl0SGFzQmVlbkNoZWNrZWQoKSBleGNlcHRpb25cbiAgICAgIGRlbGF5KDApXG4gXG4gICAgKS5zdWJzY3JpYmUoIHBheWxvYWQgPT4gdGhpcy5jaGFuZ2VUZW1wbGF0ZShwYXlsb2FkIHx8IHt9IGFzIFRlbGVwb3J0UGF5bG9hZCkgKTtcbiAgfVxuXG4gIHByaXZhdGUgY2hhbmdlVGVtcGxhdGUoeyB0ZW1wbGF0ZSwgZGF0YSB9OiBUZWxlcG9ydFBheWxvYWQpIHtcblxuICAgIC8vIEVtaXRzIHRoZSBuZXcgb3B0aW9uYWwgZGF0YSwgaWYgYW55XG4gICAgaWYodHlwZW9mKGRhdGEpICE9PSB1bmRlZmluZWQpIHsgdGhpcy5kYXRhLmVtaXQoZGF0YSk7IH1cblxuICAgIC8qKiBTa2lwcyBvbiBubyB0ZW1wbGF0ZSBjaGFuZ2VzICovXG4gICAgaWYodGVtcGxhdGUgPT09IHRoaXMubmdUZW1wbGF0ZU91dGxldCkgeyByZXR1cm47IH1cblxuICAgIC8vIENyZWF0ZXMgYSBzaW1wbGUgY2hhbmdlIG9iamVjdFxuICAgIGNvbnN0IG5nVGVtcGxhdGVPdXRsZXQgPSBuZXcgU2ltcGxlQ2hhbmdlKHRoaXMubmdUZW1wbGF0ZU91dGxldCwgdGVtcGxhdGUgfHwgdGhpcy5ob3N0LCB0aGlzLmZpcnN0Q2hhbmdlKTtcblxuICAgIC8vIFVwZGF0ZXMgdGhlIHBhcmVudCdzIHRlbXBsYXRlIHZhcmlhYmxlIGFjY29yZGluZ2x5XG4gICAgdGhpcy5uZ1RlbXBsYXRlT3V0bGV0ID0gbmdUZW1wbGF0ZU91dGxldC5jdXJyZW50VmFsdWU7XG4gICAgXG4gICAgLy8gVHJhY2tzIGZvciB0aGUgZmlyc3QgY2hhbmdlXG4gICAgdGhpcy5maXJzdENoYW5nZSA9IGZhbHNlO1xuICAgIFxuICAgIC8vIEZvcmNlcyB0aGUgY2hhbmdlIHRvIG9jY3VyXG4gICAgc3VwZXIubmdPbkNoYW5nZXMoeyBuZ1RlbXBsYXRlT3V0bGV0IH0pO1xuXG4gICAgLy8gRW1pdHMgdGhlIG5ldyB0ZW1wbGF0ZVxuICAgIHRoaXMudGVtcGxhdGUuZW1pdCh0aGlzLm5nVGVtcGxhdGVPdXRsZXQpO1xuXG4gICAgLy8gRW1pdHMgdHJ1ZSB3aGVuZXZlciB0aGUgdGVtcGxhdGUgaXNuJ3QgdGhlIGhvc3Qgb25lXG4gICAgdGhpcy5hY3RpdmUuZW1pdCh0aGlzLm5nVGVtcGxhdGVPdXRsZXQgIT09IHRoaXMuaG9zdCk7XG4gIH1cblxuICAvLyBJbnRlcmNlcHRzIHRoZSBpbnB1dCBjaGFuZ2VzXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBcbiAgICAvLyBHZXRzIHJpZCBvZiB0aGUgbmFtZSdzIFNpbXBsZUNoYW5nZSBvYmplY3RcbiAgICBpZihjaGFuZ2VzLm5hbWUpIHsgZGVsZXRlIGNoYW5nZXMubmFtZTsgfVxuICAgIFxuICAgIC8vIFNraXBzIHdoZW4gbm8gY2hhbmdlcyByZW1haW5zXG4gICAgaWYoT2JqZWN0LmtleXMoY2hhbmdlcykubGVuZ3RoID09PSAwKSB7IHJldHVybjsgfVxuICAgIFxuICAgIC8vIExldHMgdGhlIGNvbnRleHQgY2hhbmdlcyBnbyB0aHJvdWdoXG4gICAgc3VwZXIubmdPbkNoYW5nZXMoY2hhbmdlcyk7XG4gIH1cblxuICAvLyBEaXNwb3NlcyBvZiB0aGUgc3Vic2NyaXB0aW9uIG9uIGRlbGV0aW9uXG4gIG5nT25EZXN0cm95KCkgeyB0aGlzLnN1Yi51bnN1YnNjcmliZSgpOyB9XG59Il19