Angular 2.0和模态对话框

use*_*525 124 modal-dialog angular

我试图找到一些关于如何在Angular 2.0中进行确认模式对话框的示例.我一直在使用Angular 1.0的Bootstrap对话框,无法在Web上找到Angular 2.0的任何示例.我也检查了角度2.0文档没有运气.

有没有办法在Angular 2.0中使用Bootstrap对话框?

谢谢!

Ste*_*aul 196

  • 角2和以上
  • Bootstrap css(保留动画)
  • 没有JQuery
  • 没有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();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

.modal {
  background: rgba(0,0,0,0.6);
}
Run Code Online (Sandbox Code Playgroud)

该示例现在允许同时使用多个模态.(见onContainerClicked()方法).

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

为了证明,这里有一个傻瓜


Dou*_*low 55

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

它的要点是你可以在组件中包装bootstrap html和jquery初始化.我创建了一个可重用的modal组件,允许您使用模板变量触发打开.

<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>
Run Code Online (Sandbox Code Playgroud)

您只需要安装npm包并在app模块中注册模态模块:

import { Ng2Bs3ModalModule } from 'ng2-bs3-modal/ng2-bs3-modal';

@NgModule({
    imports: [Ng2Bs3ModalModule]
})
export class MyAppModule {}
Run Code Online (Sandbox Code Playgroud)

  • 嗯,是的,bootstrap依赖它,我不是在重写库的业务. (51认同)
  • 无赖 - 依赖于jquery作为依赖:( (8认同)
  • 这可以在没有jQuery的情况下完成.我使用Sam的答案以及http://koscielniak.me/post/2016/03/angular2-confirm-dialog-component/上的教程来编写服务和相关的模态组件. (2认同)

Sam*_*Sam 46

这是一种不依赖于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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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

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

}
Run Code Online (Sandbox Code Playgroud)

parent.html

<app-error-message></app-error-message>
// your html...
Run Code Online (Sandbox Code Playgroud)

  • 很好 - 可以解释`class ="模态淡入淡出显示危险"` (3认同)

zur*_*fyx 10

现在作为NPM包提供

角定制模态


@Stephen Paul 继续 ......

  • Angular 2及以上Bootstrap css(保留动画)
  • 没有JQuery
  • 没有bootstrap.js
  • 支持自定义模态内容
  • 支持多个模态在彼此之上.
  • Moduralized
  • 当模态打开时禁用滚动
  • 导航时模态会被破坏.
  • 延迟内容初始化,ngOnDestroy在退出模式时获取(ed).
  • 当模态可见时,父滚动被禁用

延迟内容初始化

为什么?

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

原始模态问题

将内容直接传递到视图实际上会在模态获取之前初始化它.即使使用*ngIf包装器,模式也无法杀死此类内容.

ng-template.ng-template在命令这样做之前不会渲染.

我-component.module.ts

...
imports: [
  ...
  ModalModule
]
Run Code Online (Sandbox Code Playgroud)

我-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>
Run Code Online (Sandbox Code Playgroud)

modal.component.ts

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

modal.component.html

<div ... *ngIf="visible">
  ...
  <div class="modal-body">
    ng-container *ngTemplateOutlet="body"></ng-container>
  </div>
Run Code Online (Sandbox Code Playgroud)

参考

我不得不说,如果没有关于网络的优秀官方和社区文件,就不可能实现.它可以帮助一些你太了解如何更好地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

完整的复制粘贴解决方案

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>
Run Code Online (Sandbox Code Playgroud)

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();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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 { }
Run Code Online (Sandbox Code Playgroud)


Fra*_*yen 7

我使用ngx-bootstrap作为我的项目.

你可以在这里找到演示

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(){}
Run Code Online (Sandbox Code Playgroud)
  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>
Run Code Online (Sandbox Code Playgroud)