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