簡體   English   中英

如何使用代碼在 Angular 2 中打開模態?

[英]How to use code to open a modal in Angular 2?

通常我們在<button>中使用data-target="#myModal"來打開一個模式。 現在我需要使用代碼來控制何時打開模式。

如果我使用[hidden]*ngIf來顯示它,我需要刪除class="modal fade" ,否則,模態將永遠不會顯示。 像這樣:

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

但是,在這種情況下,刪除class="modal fade"后,模態框不會淡入並且在背景中沒有陰影。 更糟糕的是,它會顯示在屏幕底部而不是屏幕中心。

有沒有辦法保持class="modal fade"並使用代碼打開它?

<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>

這是我找到的一種方法。 您可以添加一個隱藏按鈕:

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

然后使用代碼“單擊”按鈕打開模態:

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

這種方式可以保持模態和淡入動畫的引導樣式。

像往常一樣在 index.html 的腳本標簽中包含 jQuery。

在所有導入之后但在聲明 @Component 之前,添加:

declare var $: any;

現在,您可以在 Angular 2 TypeScript 代碼中的任何位置自由使用 jQuery:

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

參考: https : //stackoverflow.com/a/38246116/2473022

angular 2 或 4 中實現此目的的簡單方法(假設您使用的是bootstrap 4

組件.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>

組件.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';
}

以下答案參考了最新的ng-bootstrap

安裝

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 { }

組件控制器

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);
  }

}

組件 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>

我找到的最好的方法。 #lgModal或其他一些變量名放入您的模式中。

在您看來:

<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>

在您的組件中

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();
  }

}

這是我對 modal bootstrap angular2 組件的完整實現:

我認為在你的主index.html文件(用<html><body>標簽),在底部<body>標簽必須:

  <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;
}

模態.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>

以及在客戶端編輯器組件中的使用示例: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();
    }

}

客戶端-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>

當然title、showClose、mhead和mfoot都是可選參數。

我目前正在 Angular 8 中使用 Bootstrap 4.3,並希望以編程方式打開模態窗口(而不是像官方演示所示那樣實際點擊某個按鈕)。

以下方法對我有用:一般的想法是創建一個與模態窗口關聯的按鈕。 首先確定你點擊這個按鈕后,它可以打開模態。 然后使用 hashtag 給這個按鈕標簽一個 id,例如#hiddenBtn 在組件 ts 文件中, import ViewChild from @angular/core並編寫以下代碼:

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

之后,每當你想在你的組件ts代碼中打開這個模態窗口時,編寫以下代碼來模擬點擊操作

this.myHiddenBtn.nativeElement.click();

我不覺得將 JQuery 與 angular 和 bootstrap 一起使用有什么問題,因為在添加 bootstrap 時包含了它。

  1. 像這樣在導入后立即添加 $


import {.......

declare var $: any;

@component.....
  1. 模態應該有一個這樣的id

<div id="errorModal" class="modal fade bd-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" ..............

  1. 然后有一個這樣的方法

showErrorModal() { $("#errorModal").modal('show'); }

  1. 單擊按鈕或您希望的任何地方調用該方法

認為我找到了使用ngx-bootstrap的正確方法。 首先導入以下類:

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

在組件的類實現中添加一個 @ViewCild 屬性,一個打開模態的函數,不要忘記在組件類構造函數中將 modalService 設置為私有屬性:

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

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

@ViewChild 聲明的“editSomething”部分指的是組件模板文件及其模態模板實現( #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>

最后調用該方法在任何你想要的地方打開模態:

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

this.editSomethingModal是TemplateRef可能由ModalService顯示。

等等! 組件模板文件中定義的模態由組件類實現內部的調用顯示。 就我而言,我用它來顯示事件處理程序內部的模式。

我過去在沒有大量編碼的情況下這樣做的方式是..我有一個帶有id="employeeRegistered"的隱藏按鈕

在我的.ts文件中,我import ElementRef from '@angular/core'

然后在我處理完我的(click)方法上的所有內容后, (click)執行以下操作:

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

然后模態按預期顯示..

對我來說,除了@arjun-sk 解決方案( 鏈接)之外,我還必須設置超時,因為我收到了錯誤

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

我正在使用一個變量來控制顯示和隱藏,並依靠按鈕打開模態

ts 代碼:

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>

我們可以使用 jquery 來打開 bootstrap modal。

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

@ng-bootstrap/ng-bootstrap npm 我為此使用,因為在項目中使用了引導程序,對於材料,我們使用了對話框

HTML代碼

  <span (click)="openModal(modalRef)" class="form-control input-underline pl-3 ">Open Abc Modal
 </span>

模態模板

<ng-template class="custom-modal"  #modalRef let-c="close" let-d="dismiss">
   <div class="modal-header custom-modal-head"><h4 class="modal-title">List of Countries</h4>
     <button type="button" class="close" aria-label="Close" (click)="d('Cross click')">
         <img src="assets/actor/images/close.png" alt="">
      </button>
  </div>
  <div class="modal-body country-select">
       <div class="serch-field">
           <div class="row">
               <div class="col-md-12">
                 <input type="text"  class="form-control input-underline pl-3" placeholder="Search Country"
                    [(ngModel)]="countryWorkQuery" [ngModelOptions]="{standalone: true}">
                 <ul *ngIf="countries" class="ng-star-inserted">
                   <li (click)="setSelectedCountry(cntry, 'work');d('Cross click');" class="cursor-pointer"
                   *ngFor="let cntry of countries | filterNames:countryWorkQuery ">{{cntry.name}}</li>
                 </ul>
                 <span *ngIf="!modalSpinner && (!countries || countries.length<=0)">No country found</span>
                 <span *ngIf="modalSpinner" class="loader">
                     <img src="assets/images/loader.gif" alt="loader">
                 </span>
               </div>
             </div>
       </div>
 </div>
</ng-template>

Ts文件

import {NgbModal, ModalDismissReasons} from '@ng-bootstrap/ng-bootstrap';

constructor(
    private modalService: NgbModal
  ) { }

  openModal(modalContent){
     this.modalService.open(modalContent, { centered: true});
   }

簡單地說, npm install --save @types/bootstrap嘗試將鍵入版本與您的引導程序版本相匹配。 例如你有 Bootstrap 4.3.1 然后npm install --save @types/bootstrap@4.3.1

讓我解釋一下解決方案。 有點棘手.......父 HTML 文件.......

<!-- parent component html -->
your code....
<div class="d-flex align-items-center flex-nowrap justify-content-end">
    <button (click)="openCancelStandingOrder(line)" class="btn btn-primary mx-1" type="button">Delete</button>
</div>
<div *ngIf="isCancelStandingOrderOpen">
    <child-component [data]="data" (onCloseModel)="onCloseModal($event)"></child-component>
</div>

父 TS 文件

export class ParentComponent {
isCancelStandingOrderOpen: boolean = false;
data: any;
// ....
fetchData() {
// API Call
}

openCancelStandingOrder(line) {
this.isCancelStandingOrderOpen = true;
this.data = line;
}

onCloseModal(reload) {
// prevent unnessecery api calls
if (reload) {

// fetch list data again
this.fetchData();
}

// Do needful

}
}

孩子 HTML 文件

<ng-template #cancelStandingOrderModal let-modal>
    <div class="modal-header">
        <h4 class="modal-title" id="modal-basic-title">Title</h4>
        <button type="button" class="btn-close" aria-label="Close" (click)="onDismiss(modal)"></button>
    </div>
    <div class="modal-body">
        <!--  your content here -->
    </div>
    <div class="modal-footer">
        <button type="button" class="btn btn-outline-success" (click)="onSubmit(modal)">Save</button>
        <button type="button" class="btn btn-outline-dark" (click)="onExit(modal)">Cancel</button>
    </div>
</ng-template>

子 TS 文件

export class ChildComponent {
// ...
@Input() data: any; // Get data from parent
@Output() public onCloseModal: EventEmitter<boolean> = new EventEmitter();
    @ViewChild('cancelStandingOrderModal', { static: false }) public formModal: TemplateRef<any>; // Note: Target html
        instance

        // Using bootstrap modals: https://ng-bootstrap.github.io/#/components/modal/examples
        constructor(private modalService: NgbModal) { }

        ngOnInit() {
        // Any data manipulation
        }

        ngAfterViewInit() {
        this.openModal();
        }

        openModal() {
        this.modalService.open(this.formModal, {
        backdrop: false,
        centered: true,
        size: 'lg',
        keyboard: false, // disable ESC key to close
        });
        }

        onSubmit(modal) {
        // Do needful.. api calls etc....
        // ...
        this.closeModel(modal, true)
        }

        onExit(modal) {
        // Execute any mathod befor closing modal
        // like unsaved data alert etc.
        this.closeModel(modal, false)
        }


        onDismiss(modal) {
        this.closeModel(modal, false)
        }

        closeModel(modal: any, reload: boolean = false) {
        this.onCloseModal.emit(reload)
        modal.close('close');
        }
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM