Angular 2.0 и модального диалогового окна
Я пытаюсь найти некоторые примеры того, как сделать модальный диалог подтверждения в Angular 2.0. Я использую Bootstrap dialog для Angular 1.0 и не могу найти никаких примеров в интернете для Angular 2.0. Я также проверил угловые документы 2.0 без везения.
есть ли способ использовать диалог начальной загрузки с Angular 2.0?
спасибо!
9 ответов:
- угловой 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(); } } }
чтобы показать фон, вам что-то понадобится как это CSS:
.modal { background: rgba(0,0,0,0.6); }
пример теперь позволяет использовать несколько модалов одновременно. (см.
onContainerClicked()
метод).для пользователей Bootstrap 4 css, вам нужно сделать 1 незначительное изменение (потому что имя класса css было обновлено из Bootstrap 3). Эта линия:
[ngClass]="{'in': visibleAnimate}"
должен быть изменен на:[ngClass]="{'show': visibleAnimate}"
чтобы продемонстрировать, вот это plunkr
вот довольно приличный пример того, как вы можете использовать модальный Bootstrap в приложении Angular2 на GitHub.
суть его заключается в том, что вы можете обернуть инициализацию 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. Компонент ниже (Сообщение об ошибке.ts) может использоваться в качестве дочернего представления любого другого компонента. Это просто модальный бутстрап, который всегда открыт или показан. Его видимость регулируется оператором ngIf.
сообщение об ошибке.ТС
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; } }
сообщение об ошибке.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>
это пример родительского элемента управления (некоторые не относящиеся к делу код был опущен для краткость):
родитель.ТС
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']); } }); } }
родитель.HTML-код
<app-error-message></app-error-message> // your html...
Я использую 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>
теперь доступен как npm package
@Stephen Paul продолжение...
- угловой 2 и выше Bootstrap css (анимация сохраняется)
- нет JQuery
- нет bootstrap.js
- поддержка пользовательских модальных содержание
- поддержка нескольких модальностей друг другой.
- Moduralized
- отключить прокрутку, когда модальный открыт
- модальный разрушается при навигации прочь.
- ленивая инициализация контента, которая получает
ngOnDestroy
(ed) при выходе из модального режима.- родительская прокрутка отключена, когда модальная видимый
ленивая инициализация содержимого
почему?
в некоторых случаях вы можете не захотеть, чтобы модальный сохранял свой статус после закрытия, а скорее восстанавливался в исходное состояние.
оригинальная модальная проблема
передача содержимого прямо в представление фактически генерирует инициализирует его еще до того, как модальный получает его. Модальный не имеет способа убить таких содержание, даже если с помощью
*ngIf
фантик.решение
ng-template
.ng-template
не отображается, пока не будет приказано сделать это.мой компонент.модуль.ТС
... imports: [ ... ModalModule ]
мой компонент.ТС
<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>
модала.деталь.ТС
export class ModalComponent ... { @ContentChild('header') header: TemplateRef<any>; @ContentChild('body') body: TemplateRef<any>; @ContentChild('footer') footer: TemplateRef<any>; ... }
модала.деталь.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полный копировать-вставить решение
модала.деталь.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>
модала.деталь.ТС
/** * @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(); } } }
модала.модуль.ТС
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 { }
вот моя полная реализация модального bootstrap angular2 компонента:
я предполагаю, что в основной индекс.HTML-файл (с
<html>
и<body>
теги) в самом низу<body>
тег у вас есть:<script src="assets/js/jquery-2.1.1.js"></script> <script src="assets/js/bootstrap.min.js"></script>
модала.деталь.ТС:
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">×</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>
и пример использования в компоненте редактора клиента: клиент-редактировать-компонент.ТС:
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(); } }
клиент-вы можете редактировать.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>
АР необязательные параметры/теги.
Я недавно написал об этом в блоге ..
Я создал многоразовую службу, которую компонент может ввести. После ввода компонент может сообщить Службе, находится ли он в грязном состоянии, и подключиться к навигации маршрутизатора.
https://long2know.com/2017/01/angular2-menus-navigation-and-dialogs/ https://long2know.com/2017/01/angular2-dialogservice-exploring-bootstrap-part-2/
Проверьте диалог ASUI, который создается во время выполнения. Нет необходимости скрывать и показывать логику. Просто сервис создаст компонент во время выполнения с помощью AOT ASUI NPM
попробуйте использовать ng-window, это позволяет разработчику открывать и полностью контролировать несколько окон в одностраничных приложениях простым способом, без Jquery, без Bootstrap.
Доступны Конфигурации
- окне Maxmize
- свернуть
- пользовательский размер,
- Custom posation
- окно можно перетащить
- блокировать родительское окно или нет
- центр окно или нет
- передать значения в окно chield
- передать значения из окна chield в родительское окно
- прослушивание закрытия окна chield в Родительском окне
- слушайте, чтобы изменить размер события с помощью пользовательского слушателя
- открыть с максимальным размером или нет
- включение и отключение изменения размера окна
- включить и отключить максимизацию
- включить и отключить минимизацию