This plunker should open up a modal when the button is pressed. I have extended the existing ngx-modal but it throws error: Cannot read property 'nativeElement' of undefined.
Having looked at the console this is because "modalRoot" should be programatically assigned as a ViewChild handler for the modal. It doesn't seem to get defined when extended even though I've added the super() to my constructor, any ideas?
//our root app component
import {Component, NgModule, HostListener, ElementRef} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {ModalModule} from "ngx-modal";
import { Modal } from "ngx-modal";
@Component({
selector: 'ext-ngx-modal',
template: `<ng-content></ng-content>`,
})
export class NgxModalComponent extends Modal {
constructor() {
super();
}
openExt():void {
this.open();
}
@HostListener('document:keydown', ['$event'])
onkeydown(ev: KeyboardEvent) {
console.log("this.isOpened: " + this.isOpened;
}
}
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}} I am </h2>
<div class="row container-fluid">
<button (click)="myExtNgxModal.openExt()"> open my modal</button>
<ext-ngx-modal #myExtNgxModal>
<modal>
<modal-header>
<h1>Modal header</h1>
</modal-header>
<modal-content>
Press F12 see the console...press a key while modal open
</modal-content>
<modal-footer>
<button class="btn btn-primary" (click)="myModal.close()">close</button>
</modal-footer>
</modal>
</ext-ngx-modal>
</div>
</div>
`,
})
export class App {
name:string;
constructor() {
this.name = 'Angular2'
}
}
@NgModule({
imports: [ BrowserModule, ModalModule ],
declarations: [ App, NgxModalComponent ],
exports: [ NgxModalComponent ],
bootstrap: [ App ]
})
export class AppModule {}
Extending only the class - different templates
When your
NgxModalComponentcomponent extends theModalcomponent, it will inherit the code like you would imaging.The problem is that you are overriding it's template with your own. This is a problem since some of the code you have inherited relies on the template of the original
Modalcomponent.Here is an example from the source code where the
Modalis gaining access to an element in the template:When it invokes
open(), it's using this reference internally to setfocuson its native element:Since you don't have a the same
templateand no element named modalRoot, it will fail.Solution(s)
Using
ContentChild(docs)One solution is to use
ContentChildto get a reference to theModalthat is wrapped inside you template. yurzui posted a plunker showing this in this comment (yurzui created this plunker, no credit to me for that!).What he is doing is getting the modal reference and calling the
open()method on the embeddedModalinstance instead.Rethinking your approach
Another option is to rethink if your approach of extending this modal is really needed and the correct way forward. But that is up to you :)
I hope this helps!