Angular 2.0で確認モーダルダイアログを実行する方法の例を見つけようとしています。Angular 1.0のBootstrapダイアログを使用していて、Angular 2.0のWebで例を見つけることができません。私はまた、運が悪くて角度2.0のドキュメントをチェックしました。
Angular 2.0でブートストラップダイアログを使用する方法はありますか?
Angular 2.0で確認モーダルダイアログを実行する方法の例を見つけようとしています。Angular 1.0のBootstrapダイアログを使用していて、Angular 2.0のWebで例を見つけることができません。私はまた、運が悪くて角度2.0のドキュメントをチェックしました。
Angular 2.0でブートストラップダイアログを使用する方法はありますか?
回答:
`
@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}"
div.modal-footer
を削除し、を変更し.app-modal-footer
て.modal-footer
これを修正します。
これは、GitHubの Angular2アプリ内で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>
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">×</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...
class="modal fade show in danger"
@Stephen Paul 続き ...
ngOnDestroy
モーダルが終了したときに取得される遅延コンテンツの初期化。どうして?
場合によっては、閉じた後にモーダルのステータスを保持せずに、初期状態に戻す必要があります。
元のモーダル問題
コンテンツをビューに直接渡すと、実際には、モーダルが取得する前でも初期化されます。モーダルは、たとえ使用しても、そのようなコンテンツを殺す方法がありません*ngIf
ラッパー。
解決
ng-template
。 ng-template
レンダリングするように指示されるまでレンダリングしません。
my-component.module.ts
...
imports: [
...
ModalModule
]
my-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>
参考文献
ネット上の優れた公式およびコミュニティのドキュメントがなければ、それは不可能だったでしょう。それはあなた方の何人かがよりよく理解するのを助けるかもしれません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>
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 { }
私のプロジェクトではngx-bootstrapを使用しています。
ここでデモを見つけることができます
githubは こちら
使い方:
ngx-bootstrapをインストールする
モジュールにインポートする
// 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(){}
<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">×</span> </button> </div> <div class="modal-body"> This is static modal, backdrop click will not close it. Click <b>×</b> to close modal. </div> </div> </div> </div>
これが、モーダルブートストラップ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;
}
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">×</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();
}
}
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>
勿論title
、showClose
、<mhead>
および<mfoot>
オプションのパラメータ/タグAR。
bindModal(modal) {this._modal=modal;}
、次のように角度のViewChild
注釈を使用できます@ViewChild('editModal') _modal: Modal;
。これは、裏でバインディングを処理します。
実行時に作成されるASUIダイアログを確認します。非表示と表示のロジックは必要ありません。単にサービスは、AOT ASUI NPMを使用して実行時にコンポーネントを作成します
ng-windowを使用してみてください。これにより、開発者は単一のページアプリケーションで複数のウィンドウを簡単な方法で開き、フルコントロールできます。JqueryやBootstrapは不要です。
利用可能な構成
Angular 7 + NgBootstrap
主要コンポーネントからモーダルを開き、結果をそれに返す簡単な方法。私が欲しかったものです。最初から新しいプロジェクトを作成し、ngbootstrapをインストールし、Modalを作成する手順を追ったチュートリアルを作成しました。クローンを作成するか、ガイドに従ってください。
これがAngularの新機能に役立つことを願っています。
https://github.com/wkaczurba/modal-demo
詳細:
modal-simpleテンプレート(modal-simple.component.html):
<ng-template #content let-modal>
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">Are you sure?</h4>
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>You have not finished reading my code. Are you sure you want to close?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="modal.close('yes')">Yes</button>
<button type="button" class="btn btn-outline-dark" (click)="modal.close('no')">No</button>
</div>
</ng-template>
modal-simple.component.ts:
import { Component, OnInit, ViewChild, Output, EventEmitter } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'app-modal-simple',
templateUrl: './modal-simple.component.html',
styleUrls: ['./modal-simple.component.css']
})
export class ModalSimpleComponent implements OnInit {
@ViewChild('content') content;
@Output() result : EventEmitter<string> = new EventEmitter();
constructor(private modalService : NgbModal) { }
open() {
this.modalService.open(this.content, {ariaLabelledBy: 'modal-simple-title'})
.result.then((result) => { console.log(result as string); this.result.emit(result) },
(reason) => { console.log(reason as string); this.result.emit(reason) })
}
ngOnInit() {
}
}
そのデモ(app.component.html)-リターンイベントを処理する簡単な方法:
<app-modal-simple #mymodal (result)="onModalClose($event)"></app-modal-simple>
<button (click)="mymodal.open()">Open modal</button>
<p>
Result is {{ modalCloseResult }}
</p>
app.component.ts-モーダルが閉じられるとonModalClosedが実行されます。
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
modalCloseResult : string;
title = 'modal-demo';
onModalClose(reason : string) {
this.modalCloseResult = reason;
}
}
乾杯