I tried to follow this and this to no avail. In the end I just decided to solve the problem my own way with some singleton state which holds an object like so:
import { President } from '../models/president.model';
import { OverlayRef } from '@angular/cdk/overlay';
export class ModalMetadata {
overlayRef: OverlayRef;
president: President;
public closeAction(){
if(this.overlayRef) {
this.overlayRef.dispose();
this.overlayRef = null;
}
}
}
My service is such:
import { Injectable, OnDestroy } from '@angular/core';
import { Overlay } from '@angular/cdk/overlay';
import { President } from '../models/president.model';
import { ModalMetadata } from '../models/modalMetadata.model';
import { ModalComponent } from '../layout/modal.component';
import { ComponentPortal } from '@angular/cdk/portal';
import { Router } from '@angular/router';
import { ISubscription } from 'rxjs/Subscription';
@Injectable()
export class ModalService {
private backingStore: ModalMetadata;
private subscription: ISubscription;
constructor(private overlay: Overlay, private router: Router) {
this.subscription = router.events.subscribe(()=> {
if (this.backingStore) this.backingStore.closeAction();
});
}
public open(president:President) {
const filePreviewPortal = new ComponentPortal(ModalComponent);
if (!this.backingStore) this.backingStore = new ModalMetadata();
this.backingStore.president = president;
if (!this.backingStore.overlayRef) {
this.backingStore.overlayRef = this.overlay.create();
this.backingStore.overlayRef.attach(filePreviewPortal);
}
}
public getSingletonState():ModalMetadata {
return this.backingStore;
}
ngOnDestroy(){
this.subscription.unsubscribe();
}
}
I have some inversion of control in TypeScript going on and thus there is a contract for the service. It looks like this:
import { President } from '../models/president.model';
import { ModalMetadata } from '../models/modalMetadata.model';
export class ModalContract {
constructor() {}
public open: (president:President) => void;
public getSingletonState: () => ModalMetadata;
}
My component that I spit out in a modal looks like this:
import { Component, OnInit } from '@angular/core';
import { ModalMetadata } from '../models/modalMetadata.model';
import { ModalContract } from '../contracts/modal.contract';
@Component({
selector: 'modal',
templateUrl: './modal.component.html',
styleUrls: ['./modal.component.css']
})
export class ModalComponent implements OnInit {
private modalMetadata: ModalMetadata;
constructor(public modalContract: ModalContract) {}
ngOnInit() {
this.modalMetadata = this.modalContract.getSingletonState();
}
close() {
this.modalMetadata.closeAction();
}
}
The template for the component is super simple. You will note that you may click an X to close to modal! Also you may have noticed above that the modal closes itself if you navigate away elsewhere.
{{ modalMetadata.president.Name}}... <a (click)="close()">X</a>
To use this stuff just call the open method in the service. This is all an better bake out of what I originally wrote about here.
Addendum 12/1/2018: I guess the "singleton state" isn't really a singleton as the state mutates. No... I spoke too soon. A singleton doesn't have to be constant. It's OK.
No comments:
Post a Comment