Best practice for calling the NgbModal open method

Patrik Nilsson picture Patrik Nilsson · Sep 13, 2016 · Viewed 54.4k times · Source

Toying around with the NgbModal and want to trigger the open method -> open(content: string | TemplateRef<any>, options: NgbModalOptions) <- from somewhere else than the template code. In my case case I want to pass a string as a parameter when running the method in the .ts file of my component. When running the method via a button in the html file like so: <button (click)="open(content)">Launch demo modal</button>, the code works great, of course with all the code from within the <template></template> in the html file.

Trying to accomplish something with this:

logoutScreenOptions: NgbModalOptions = {
    backdrop: 'static',
    keyboard: false
};

lockedWindow: NgbModalRef;

lockedScreenContent= `
    <template #content let-c="close" let-d="dismiss">
        <div class="modal-header" style="text-align: center">
            <h3 class="modal-title">Title</h3>
        </div>
        <div class="modal-body">
            <p>Body</p>
        </div>
        <div class="modal-footer">
            <p>Footer</p>
        </div>
    </template>
`;

openLockedScreen(){
    this.open(this.lockedScreenContent);
}

open(content) {
    console.log(content);
    this.lockedWindow = this.modalService.open(content, this.logoutScreenOptions);
    this.lockedWindow.result.then((result) => {
        this.closeResult = `Closed with: ${result}`;
    }, (reason) => {
        this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
    });
}

Code runs with no errors, and the modal opens like so: Modal without rendered content ...which is not exactly what I want!

Also tried like this, with exactly the same result:

lockedScreenContent= `
    <div class="modal-header" style="text-align: center">
        <h3 class="modal-title">Title</h3>
    </div>
    <div class="modal-body">
        <p>Body</p>
    </div>
    <div class="modal-footer">
        <p>Footer</p>
    </div>
`;

What am I missing? Wouldn't it be possible to just pass a string as the "content" parameter?

Can't see to get my head around how to use a templateRef parameter from the ts file either!

Answer

pkozlowski.opensource picture pkozlowski.opensource · Sep 13, 2016

As of today the open method of https://ng-bootstrap.github.io/#/components/modal has the following signature: open(content: string | TemplateRef<any>, options: NgbModalOptions). As you can see from this signature you can open a modal providing content as:

  • string
  • TemplateRef

The string-typed argument is not very interesting - in fact it was mostly added to aid debugging / unit-testing. By using it you can pass just ... well, a piece of text , without any markup not Angular directives. As such it is really a debug tool and not something that is useful in real-life scenarios.

The TemplateRef argument is more interesting as it allows you to pass markup + directives to be displayed. You can get a hand on a TemplateRef by doing <template #refVar>...content goes here...</template> somewhere in your component template (a template of a component from which you plan to open a modal). As such the TemplateRef argument is powerful as it allows you to have markup, directives, other components etc. The downside is that TemplateRef is useful only if you are opening a modal from a component with a template.

I've got an impression that you are looking for the feature that is planned but not implemented yet - ability to open a modal with a component type as content. It would work as follows: modalService.open(MyComponentWithContent). As I've mentioned this is part of the roadmap but not implemented yet. You can track this feature by following https://github.com/ng-bootstrap/ng-bootstrap/issues/680