Last active
May 20, 2024 02:42
-
-
Save mfp22/479a6860510286e69d9cb7ea3a448d5e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
Component, | |
Input, | |
OnChanges, | |
SimpleChanges, | |
OnDestroy, | |
} from '@angular/core'; | |
import { | |
MatDialogRef, | |
MatDialogConfig, | |
MatDialog, | |
} from '@angular/material/dialog'; | |
import { Observable } from 'rxjs'; | |
// Separate files | |
export interface AppDialogState { | |
[index: string]: Observable<any>; | |
} | |
export interface AppDialogActions { | |
[index: string]: Function; | |
} | |
@Component({ | |
selector: 'app-dialog-content-component', | |
template: '', | |
}) | |
export class DialogContentComponent { | |
state: AppDialogState; | |
actions: AppDialogActions; | |
} | |
@Component({ | |
selector: 'app-dialog', | |
template: '', | |
}) | |
export class AppDialogComponent | |
implements OnChanges, OnDestroy, DialogContentComponent { | |
// Can't find a type that this.dialog.open likes without importing something obscure | |
@Input() component: any; | |
@Input() state: AppDialogState = {}; | |
@Input() actions: AppDialogActions = {}; | |
@Input() open = false; | |
@Input() config: MatDialogConfig; | |
dialogRef: MatDialogRef<any>; | |
constructor(public dialog: MatDialog) {} | |
ngOnChanges(changes: SimpleChanges) { | |
if (changes.open) { | |
this.applyDialogState(changes.open.currentValue); | |
} | |
} | |
ngOnDestroy() { | |
// setTimeout because applyDialogState is sometimes on a timeout | |
// when this runs and can reopen the dialog | |
// after this component is already destroyed. | |
setTimeout(() => this.closeDialog()); | |
} | |
applyDialogState = (shouldBeOpen: boolean) => { | |
setTimeout(() => { | |
// Change detection console error without this | |
const isOpen = !!this.dialogRef; | |
if (!isOpen && shouldBeOpen) { | |
this.openDialog(); | |
} else if (isOpen && !shouldBeOpen) { | |
this.closeDialog(); | |
} | |
}); | |
}; | |
openDialog() { | |
this.dialogRef = this.dialog.open(this.component, this.config); | |
this.dialogRef.componentInstance.state = this.state; | |
this.dialogRef.componentInstance.actions = this.actions; | |
} | |
closeDialog() { | |
if (this.dialogRef) { | |
this.dialogRef.close(); | |
} | |
this.dialogRef = undefined; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Obviously the problem was on my side...
Didn't think of referencing an ng-template.
It works flawlessly now!
Just for the sake of clarity, if anyone is dumb enough to be in my same shoes, it's used like this:
<app-dialog [component]="dialogComponent" [open]="open$ | async"></app-dialog>
<ng-template #dialogComponent> ... something ... </ng-template>