Angular 2.0和Modal对话框

我正在试图find一些关于如何在Angular 2.0中做一个Confirmation模式对话框的例子。 我一直在使用Angular 1.0的Bootstrap对话框,在Angular 2.0的Web上找不到任何示例。 我也检查了angular2.0文档没有运气。

有没有办法与Angular 2.0一起使用Bootstrap对话框?

谢谢 !

  • angular2和以上
  • 引导CSS(animation保存)
  • 没有JQuery
  • NO bootstrap.js
  • 支持自定义模式内容 (就像接受的答案)
  • 最近增加了对多个模块的支持。

`

@Component({ selector: 'app-component', template: ` <button type="button" (click)="modal.show()">test</button> <app-modal #modal> <div class="app-modal-header"> header </div> <div class="app-modal-body"> Whatever content you like, form fields, anything </div> <div class="app-modal-footer"> <button type="button" class="btn btn-default" (click)="modal.hide()">Close</button> <button type="button" class="btn btn-primary">Save changes</button> </div> </app-modal> ` }) export class AppComponent { } @Component({ selector: 'app-modal', template: ` <div (click)="onContainerClicked($event)" class="modal fade" tabindex="-1" [ngClass]="{'in': visibleAnimate}" [ngStyle]="{'display': visible ? 'block' : 'none', 'opacity': visibleAnimate ? 1 : 0}"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <ng-content select=".app-modal-header"></ng-content> </div> <div class="modal-body"> <ng-content select=".app-modal-body"></ng-content> </div> <div class="modal-footer"> <ng-content select=".app-modal-footer"></ng-content> </div> </div> </div> </div> ` }) export class ModalComponent { public visible = false; public visibleAnimate = false; public show(): void { this.visible = true; setTimeout(() => this.visibleAnimate = true, 100); } public hide(): void { this.visibleAnimate = false; setTimeout(() => this.visible = false, 300); } public onContainerClicked(event: MouseEvent): void { if ((<HTMLElement>event.target).classList.contains('modal')) { this.hide(); } } } 

为了显示背景 ,你需要像这样的CSS:

 .modal { background: rgba(0,0,0,0.6); } 

现在的例子允许同时使用多个模态 。 (请参阅onContainerClicked()方法)。

对于Bootstrap 4 css用户 ,您需要进行1次小改动(因为css类名是从Bootstrap 3更新的)。 这行: [ngClass]="{'in': visibleAnimate}"应改为: [ngClass]="{'show': visibleAnimate}"

为了演示,这里是一个高级的游戏

这里有一个很好的例子,说明如何在GitHub的Angular2应用程序中使用Bootstrap模式。

它的要点是你可以将引导html和jquery初始化包装在一个组件中。 我创build了一个可重用的modal组件,允许您使用模板variables触发打开。

 <button type="button" class="btn btn-default" (click)="modal.open()">Open me!</button> <modal #modal> <modal-header [show-close]="true"> <h4 class="modal-title">I'm a modal!</h4> </modal-header> <modal-body> Hello World! </modal-body> <modal-footer [show-default-buttons]="true"></modal-footer> </modal> 

您只需要安装npm软件包,并将模块模块注册到您的应用程序模块中:

 import { Ng2Bs3ModalModule } from 'ng2-bs3-modal/ng2-bs3-modal'; @NgModule({ imports: [Ng2Bs3ModalModule] }) export class MyAppModule {} 

这是一个简单的方法,不依赖于jquery或除Angular 2以外的任何其他库。下面的组件(errorMessage.ts)可以用作任何其他组件的子视图。 它只是一个始终打开或显示的自举模式。 它的可见性是由ngIf语句控制的。

errorMessage.ts

 import { Component } from '@angular/core'; @Component({ selector: 'app-error-message', templateUrl: './app/common/errorMessage.html', }) export class ErrorMessage { private ErrorMsg: string; public ErrorMessageIsVisible: boolean; showErrorMessage(msg: string) { this.ErrorMsg = msg; this.ErrorMessageIsVisible = true; } hideErrorMsg() { this.ErrorMessageIsVisible = false; } } 

errorMessage.html

 <div *ngIf="ErrorMessageIsVisible" class="modal fade show in danger" id="myModal" role="dialog"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">&times;</button> <h4 class="modal-title">Error</h4> </div> <div class="modal-body"> <p>{{ErrorMsg}}</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" (click)="hideErrorMsg()">Close</button> </div> </div> </div> </div> 

这是父控制的示例(为了简洁,省略了一些不相关的代码):

parent.ts

 import { Component, ViewChild } from '@angular/core'; import { NgForm } from '@angular/common'; import {Router, RouteSegment, OnActivate, ROUTER_DIRECTIVES } from '@angular/router'; import { OnInit } from '@angular/core'; import { Observable } from 'rxjs/Observable'; @Component({ selector: 'app-application-detail', templateUrl: './app/permissions/applicationDetail.html', directives: [ROUTER_DIRECTIVES, ErrorMessage] // Note ErrorMessage is a directive }) export class ApplicationDetail implements OnActivate { @ViewChild(ErrorMessage) errorMsg: ErrorMessage; // ErrorMessage is a ViewChild // yada yada onSubmit() { let result = this.permissionsService.SaveApplication(this.Application).subscribe(x => { x.Error = true; x.Message = "This is a dummy error message"; if (x.Error) { this.errorMsg.showErrorMessage(x.Message); } else { this.router.navigate(['/applicationsIndex']); } }); } } 

parent.html

 <app-error-message></app-error-message> // your html... 

这里是我完全实现模态bootstrap angular2组件:

我假设在你的主体index.html文件(在<html> <body>标签底部有<html><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; } 

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> 

以及客户端编辑器组件中的用法示例: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> 

当然titleshowClose<mhead><mfoot> ar可选参数/标记。

我为我的项目使用ngx-bootstrap 。

你可以在这里find演示

github在这里

如何使用:

  1. 安装ngx-bootstrap

  2. 导入到你的模块

 // RECOMMENDED (doesn't work with system.js) import { ModalModule } from 'ngx-bootstrap/modal'; // or import { ModalModule } from 'ngx-bootstrap'; @NgModule({ imports: [ModalModule.forRoot(),...] }) export class AppModule(){} 
  1. 简单的静态模态
 <button type="button" class="btn btn-primary" (click)="staticModal.show()">Static modal</button> <div class="modal fade" bsModal #staticModal="bs-modal" [config]="{backdrop: 'static'}" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true"> <div class="modal-dialog modal-sm"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title pull-left">Static modal</h4> <button type="button" class="close pull-right" aria-label="Close" (click)="staticModal.hide()"> <span aria-hidden="true">&times;</span> </button> </div> <div class="modal-body"> This is static modal, backdrop click will not close it. Click <b>&times;</b> to close modal. </div> </div> </div> </div> 

我最近在博客上写这个..

我创build了一个组件可以注入的可重用服务。 一旦注入,组件就可以与服务进行通信,无论它是否处于肮脏的状态,并绑定到路由器导航中。

https://long2know.com/2017/01/angular2-menus-navigation-and-dialogs/ https://long2know.com/2017/01/angular2-dialogservice-exploring-bootstrap-part-2/

检查在运行时创build的ASUI对话框。 没有必要隐藏和显示逻辑。 简单的服务将在运行时使用AOT ASUI NPM创build一个组件

现在可作为NPM包使用

angular定制模态


@Stephen Paul 继续 …

  • angular2和引导程序的CSS(animation保存)
  • 没有JQuery
  • NO bootstrap.js
  • 支持自定义模态内容
  • 支持多个模式在彼此之上。
  • Moduralized
  • 模态打开时禁止滚动
  • 离开时,莫代尔被毁灭。
  • 惰性内容初始化,在退出模式时获取ngOnDestroy (ed)。
  • 当模式可见时,父级滚动禁用

懒惰的内容初始化

为什么?

在某些情况下,您可能不希望模态在closures后保持其状态,而是恢复到初始状态。

原始的模态问题

直接将内容传递到视图中实际上会在模式获取之前生成它。 即使使用*ngIf包装,模式也没有杀死这种内容的方法。

ng-templateng-template不会渲染,直到命令这样做。

我-component.module.ts

 ... imports: [ ... ModalModule ] 

我-component.ts

 <button (click)="reuseModal.open()">Open</button> <app-modal #reuseModal> <ng-template #header></ng-template> <ng-template #body> <app-my-body-component> <!-- This component will be created only when modal is visible and will be destroyed when it's not. --> </app-my-body-content> <ng-template #footer></ng-template> </app-modal> 

modal.component.ts

 export class ModalComponent ... { @ContentChild('header') header: TemplateRef<any>; @ContentChild('body') body: TemplateRef<any>; @ContentChild('footer') footer: TemplateRef<any>; ... } 

modal.component.html

 <div ... *ngIf="visible"> ... <div class="modal-body"> ng-container *ngTemplateOutlet="body"></ng-container> </div> 

参考

我必须说,没有围绕networking的优秀的官方和社区文件是不可能的。 它可能会帮助你们更好地了解ng-template*ngTemplateOutlet@ContentChild工作的。

https://angular.io/api/common/NgTemplateOutlet
https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet/
https://medium.com/claritydesignsystem/ng-content-the-hidden-docs-96a29d70d11b
https://netbasal.com/understanding-viewchildren-contentchildren-and-querylist-in-angular-896b0c689f6e
https://netbasal.com/understanding-viewchildren-contentchildren-and-querylist-in-angular-896b0c689f6e

完整的复制粘贴解决scheme

modal.component.html

 <div (click)="onContainerClicked($event)" class="modal fade" tabindex="-1" [ngClass]="{'in': visibleAnimate}" [ngStyle]="{'display': visible ? 'block' : 'none', 'opacity': visibleAnimate ? 1 : 0}" *ngIf="visible"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <ng-container *ngTemplateOutlet="header"></ng-container> <button class="close" data-dismiss="modal" type="button" aria-label="Close" (click)="close()">×</button> </div> <div class="modal-body"> <ng-container *ngTemplateOutlet="body"></ng-container> </div> <div class="modal-footer"> <ng-container *ngTemplateOutlet="footer"></ng-container> </div> </div> </div> </div> 

modal.component.ts

 /** * @Stephen Paul https://stackoverflow.com/a/40144809/2013580 * @zurfyx https://stackoverflow.com/a/46949848/2013580 */ import { Component, OnDestroy, ContentChild, TemplateRef } from '@angular/core'; @Component({ selector: 'app-modal', templateUrl: 'modal.component.html', styleUrls: ['modal.component.scss'], }) export class ModalComponent implements OnDestroy { @ContentChild('header') header: TemplateRef<any>; @ContentChild('body') body: TemplateRef<any>; @ContentChild('footer') footer: TemplateRef<any>; public visible = false; public visibleAnimate = false; ngOnDestroy() { // Prevent modal from not executing its closing actions if the user navigated away (for example, // through a link). this.close(); } open(): void { document.body.style.overflow = 'hidden'; this.visible = true; setTimeout(() => this.visibleAnimate = true, 200); } close(): void { document.body.style.overflow = 'auto'; this.visibleAnimate = false; setTimeout(() => this.visible = false, 100); } onContainerClicked(event: MouseEvent): void { if ((<HTMLElement>event.target).classList.contains('modal')) { this.close(); } } } 

modal.module.ts

 import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ModalComponent } from './modal.component'; @NgModule({ imports: [ CommonModule, ], exports: [ModalComponent], declarations: [ModalComponent], providers: [], }) export class ModalModule { } 

尝试使用ng-window,它允许开发人员以简单的方式打开和完全控制单个页面应用程序中的多个窗口,无需Jquery,No Bootstrap。

在这里输入图像描述

Avilable Configration

  • 最大化窗口
  • 最小化窗口
  • 自定义大小,
  • 自定义位置
  • 该窗口是可拖动的
  • 阻止父窗口或不
  • 居中或不居中
  • 将值传递给chield窗口
  • 将值从chield窗口传递给父窗口
  • 监听父窗口closureschield窗口
  • 使用您的自定义侦听器侦听resize事件
  • 以最大尺寸打开或不打开
  • 启用和禁用窗口大小调整
  • 启用和禁用最大化
  • 启用和禁用最小化
Interesting Posts