Best practice for calling the NgbModal open method

2019-04-21 13:41发布

问题:

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!

回答1:

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



回答2:

You can now do the following...

Lets say you have a model component Confirm model that you want to use it in any other component.

  1. ModelComponentName is added to the declarations and entryComponent sections in the module.ts
  2. Dont forget to add NgbModule.forRoot() in the imports of your module file which contains the declarations you mentioned above.
  3. Ensure that your model component template is inside div tag and not the ng-template tag.

You can then use the following open method from any other component.

modalReference: NgbModalRef; constructor(private modalService: NgbModal) { } this.modalReference = this.modalService.open(ModelComponentName, {backdrop: 'static',size: 'lg', keyboard: false, centered: true});