How to use code to open a modal in Angular 2?

时光总嘲笑我的痴心妄想 提交于 2019-11-27 05:40:45

问题


Usually we use data-target="#myModal" in the <button> to open a modal. Right now I need use codes to control when to open the modal.

If I use [hidden] or *ngIf to show it, I need remove class="modal fade", otherwise, the modal will never show. Like this:

<div [hidden]="hideModal" id="myModal">

However, in this case, after removing class="modal fade", the modal won't fade in and has no shade in the background. And what's worse, it will show at the screen bottom instead of screen center.

Is there a way to keep class="modal fade" and use code to open it?

<button type="button" data-toggle="modal" data-target="#myModal">Open Modal</button>

<div id="myModal" class="modal fade">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-body">
        <p>Some text in the modal.</p>
      </div>
    </div>
  </div>
</div>

回答1:


This is one way I found. You can add a hidden button:

<button id="openModalButton" [hidden]="true" data-toggle="modal" data-target="#myModal">Open Modal</button>

Then use the code to "click" the button to open the modal:

document.getElementById("openModalButton").click();

This way can keep the bootstrap style of the modal and the fade in animation.




回答2:


Include jQuery as usual inside script tags in index.html.

After all the imports but before declaring @Component, add:

declare var $: any;

Now you are free to use jQuery anywhere in your Angular 2 TypeScript code:

$("#myModal").modal('show');

Reference: https://stackoverflow.com/a/38246116/2473022




回答3:


Easy way to achieve this in angular 2 or 4 (Assuming that you are using bootstrap 4)

Component.html

<button type="button" (click)="openModel()">Open Modal</button>

<div #myModel class="modal fade">
  <div class="modal-dialog">
    <div class="modal-content">
     <div class="modal-header">
        <h5 class="modal-title ">Title</h5>
        <button type="button" class="close" (click)="closeModel()">
            <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <p>Some text in the modal.</p>
      </div>
    </div>
  </div>
</div>

Component.ts

import {Component, OnInit, ViewChild} from '@angular/core';

@ViewChild('myModal') myModal;

openModel() {
  this.myModal.nativeElement.className = 'modal fade show';
}
closeModel() {
   this.myModal.nativeElement.className = 'modal hide';
}



回答4:


Here is my full implementation of modal bootstrap angular2 component:

I assume that in your main index.html file (with <html> and <body> tags) at the bottom of <body> tag you have:

  <script src="assets/js/jquery-2.1.1.js"></script>
  <script src="assets/js/bootstrap.min.js"></script>

modal.component.ts:

import { Component, Input, Output, ElementRef, EventEmitter, AfterViewInit } from '@angular/core';

declare var $: any;// this is very importnant (to work this line: this.modalEl.modal('show')) - don't do this (becouse this owerride jQuery which was changed by bootstrap, included in main html-body template): let $ = require('../../../../../node_modules/jquery/dist/jquery.min.js');

@Component({
  selector: 'modal',
  templateUrl: './modal.html',
})
export class Modal implements AfterViewInit {

    @Input() title:string;
    @Input() showClose:boolean = true;
    @Output() onClose: EventEmitter<any> = new EventEmitter();

    modalEl = null;
    id: string = uniqueId('modal_');

    constructor(private _rootNode: ElementRef) {}

    open() {
        this.modalEl.modal('show');
    }

    close() {
        this.modalEl.modal('hide');
    }

    closeInternal() { // close modal when click on times button in up-right corner
        this.onClose.next(null); // emit event
        this.close();
    }

    ngAfterViewInit() {
        this.modalEl = $(this._rootNode.nativeElement).find('div.modal');
    }

    has(selector) {
        return $(this._rootNode.nativeElement).find(selector).length;
    }
}

let modal_id: number = 0;
export function uniqueId(prefix: string): string {
    return prefix + ++modal_id;
}

modal.html:

<div class="modal inmodal fade" id="{{modal_id}}" tabindex="-1" role="dialog"  aria-hidden="true" #thisModal>
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header" [ngClass]="{'hide': !(has('mhead') || title) }">
                <button *ngIf="showClose" type="button" class="close" (click)="closeInternal()"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
                <ng-content select="mhead"></ng-content>
                <h4 *ngIf='title' class="modal-title">{{ title }}</h4>
            </div>
            <div class="modal-body">
                <ng-content></ng-content>
            </div>

            <div class="modal-footer" [ngClass]="{'hide': !has('mfoot') }" >
                <ng-content select="mfoot"></ng-content>
            </div>
        </div>
    </div>
</div>

And example of usage in client Editor component: client-edit-component.ts:

import { Component } from '@angular/core';
import { ClientService } from './client.service';
import { Modal } from '../common';

@Component({
  selector: 'client-edit',
  directives: [ Modal ],
  templateUrl: './client-edit.html',
  providers: [ ClientService ]
})
export class ClientEdit {

    _modal = null;

    constructor(private _ClientService: ClientService) {}

    bindModal(modal) {this._modal=modal;}

    open(client) {
        this._modal.open();
        console.log({client});
    }

    close() {
        this._modal.close();
    }

}

client-edit.html:

<modal [title]='"Some standard title"' [showClose]='true' (onClose)="close()" #editModal>{{ bindModal(editModal) }}
    <mhead>Som non-standart title</mhead>
    Some contents
    <mfoot><button calss='btn' (click)="close()">Close</button></mfoot>
</modal>

Ofcourse title, showClose, mhead and mfoot ar optional parameters.




回答5:


Best way I have found. Put #lgModal or some other variable name in your modal.

In your view:

<div bsModal #lgModal="bs-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" (click)="lgModal.hide()" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
        <h4 class="modal-title">Large modal</h4>
      </div>
      <div class="modal-body">
        ...
      </div>
    </div>
  </div>
</div>

In your component

import {Component, ViewChild, AfterViewInit} from '@angular/core';
import {CORE_DIRECTIVES} from '@angular/common';
// todo: change to ng2-bootstrap
import {MODAL_DIRECTIVES, BS_VIEW_PROVIDERS} from 'ng2-bootstrap/ng2-bootstrap';
import {ModalDirective} from 'ng2-bootstrap/ng2-bootstrap';


@Component({
  selector: 'modal-demo',
  directives: [MODAL_DIRECTIVES, CORE_DIRECTIVES],
  viewProviders:[BS_VIEW_PROVIDERS],
  templateUrl: '/app/components/modals/modalDemo.component.html'
})
export class ModalDemoComponent implements AfterViewInit{

  @ViewChild('childModal') public childModal: ModalDirective;
  @ViewChild('lgModal') public lgModal: ModalDirective;

  public showChildModal():void {
    this.childModal.show();
  }

  public hideChildModal():void {
    this.childModal.hide();
  }

  ngAfterViewInit() {
      this.lgModal.show();
  }

}



回答6:


The below answer is in reference to the latest ng-bootstrap

Install

npm install --save @ng-bootstrap/ng-bootstrap

app.module.ts

import {NgbModule} from '@ng-bootstrap/ng-bootstrap';

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...

    NgbModule

  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Component Controller

import { TemplateRef, ViewChild } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'app-app-registration',
  templateUrl: './app-registration.component.html',
  styleUrls: ['./app-registration.component.css']
})

export class AppRegistrationComponent implements OnInit {

  @ViewChild('editModal') editModal : TemplateRef<any>; // Note: TemplateRef

  constructor(private modalService: NgbModal) { }

  openModal(){
    this.modalService.open(this.editModal);
  }

}

Component HTML

<ng-template #editModal let-modal>

<div class="modal-header">
  <h4 class="modal-title" id="modal-basic-title">Edit Form</h4>
  <button type="button" class="close" aria-label="Close" (click)="modal.dismiss()">
    <span aria-hidden="true">&times;</span>
  </button>
</div>

<div class="modal-body">

  <form>
    <div class="form-group">
      <label for="dateOfBirth">Date of birth</label>
      <div class="input-group">
        <input id="dateOfBirth" class="form-control" placeholder="yyyy-mm-dd" name="dp" ngbDatepicker #dp="ngbDatepicker">
        <div class="input-group-append">
          <button class="btn btn-outline-secondary calendar" (click)="dp.toggle()" type="button"></button>
        </div>
      </div>
    </div>
  </form>

</div>

<div class="modal-footer">
  <button type="button" class="btn btn-outline-dark" (click)="modal.close()">Save</button>
</div>

</ng-template>



回答7:


Think I found the correct way to do it using ngx-bootstrap. First import following classes:

import { ViewChild } from '@angular/core';
import { BsModalService, ModalDirective } from 'ngx-bootstrap/modal';
import { BsModalRef } from 'ngx-bootstrap/modal/bs-modal-ref.service';

Inside the class implementation of your component add a @ViewCild property, a function to open the modal and do not forget to setup modalService as a private property inside the components class constructor:

@ViewChild('editSomething') editSomethingModal : TemplateRef<any>;
...

modalRef: BsModalRef;
openModal(template: TemplateRef<any>) {
  this.modalRef = this.modalService.show(template);
}
...
constructor(
private modalService: BsModalService) { }

The 'editSomething' part of the @ViewChild declaration refers to the component template file and its modal template implementation (#editSomething):

...
<ng-template #editSomething>
  <div class="modal-header">
  <h4 class="modal-title pull-left">Edit ...</h4>
  <button type="button" class="close pull-right" aria-label="Close" 
   (click)="modalRef.hide()">
    <span aria-hidden="true">&times;</span>
  </button>
  </div>

  <div class="modal-body">
    ...
  </div>


  <div class="modal-footer">
    <button type="button" class="btn btn-default"
        (click)="modalRef.hide()"
        >Close</button>
  </div>
</ng-template>

And finaly call the method to open the modal wherever you want like so:

console.log(this.editSomethingModal);
this.openModal( this.editSomethingModal );

this.editSomethingModal is a TemplateRef that could be shown by the ModalService.

Et voila! The modal defined in your component template file is shown by a call from inside your component class implementation. In my case I used this to show a modal from inside an event handler.




回答8:


I'm currently using Bootstrap 4.3 in Angular 8 and want to open modal window programmatically (without actually clicking on some button as the official demo shows).

Following method works for me: The general idea is to create a button associated to a modal window. First make sure after you click this button, it can open the modal. Then give this button tag an id using hashtag, for example #hiddenBtn. In component ts file, import ViewChild from @angular/core and write below code:

@ViewChild('hiddenBtn', {static: false}) myHiddenBtn;

After that, whenever you want to open this modal window in your component ts code, write following code to simulate click operation

this.myHiddenBtn.nativeElement.click();



回答9:


The Way i used to do it without lots of coding is.. I have the hidden button with the id="employeeRegistered"

On my .ts file I import ElementRef from '@angular/core'

Then after I process everything on my (click) method do as follow:

this.el.nativeElement.querySelector('#employeeRegistered').click();

then the modal displays as expected..




回答10:


For me I had to settimeout in addition to @arjun-sk solution's (link), as I was getting the error

setTimeout(() => {
      this.modalService.open(this.loginModal, { centered: true })
    }, 100); 



回答11:


I am using a variable to control show and hide and rely on the button the open the modal

ts code:

showModel(){
  this.showModal = true;
}

html:

<button type="button" data-toggle="modal" data-target="#myModal" (click)="showModel()>Open Modal</button>

<div *ngIf="showModal" >
  <div id="myModal" class="modal fade">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-body">
                <p>Some text in the modal.</p>
            </div>
        </div>
    </div>
</div>




回答12:


We can use jquery to open bootstrap modal.

ngAfterViewInit() { 
      $('#scanModal').modal('show'); 
}


来源:https://stackoverflow.com/questions/35400811/how-to-use-code-to-open-a-modal-in-angular-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!