it-swarm.com.de

Angular 2.0 und Modal Dialog

Ich versuche, einige Beispiele zu finden, wie ein modifizierter Bestätigungsdialog in Angular 2.0 ausgeführt wird. Ich habe den Bootstrap-Dialog für Angular 1.0 verwendet und konnte für Angular 2.0 keine Beispiele im Web finden. Ich habe auch eckige 2.0-Dokumente ohne Erfolg geprüft.

Gibt es eine Möglichkeit, den Bootstrap-Dialog mit Angular 2.0 zu verwenden?

Vielen Dank!

123
user636525
  • Winkel 2 und höher
  • Bootstrap css (Animation bleibt erhalten) 
  • NO JQuery
  • NO bootstrap.js
  • Unterstützt benutzerdefinierten modalen Inhalt (genau wie akzeptierte Antwort)
  • Kürzlich hinzugefügte Unterstützung für multiple Modals übereinander.

`

@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();
    }
  }
}

Um den Hintergrund anzuzeigen, benötigen Sie folgendes CSS:

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

Das Beispiel erlaubt jetzt mehrere Modale gleichzeitig. (siehe die onContainerClicked()-Methode).

Für Benutzer von Bootstrap 4 css müssen Sie eine geringfügige Änderung vornehmen (da der Name einer CSS-Klasse von Bootstrap 3 aktualisiert wurde). Diese Zeile: [ngClass]="{'in': visibleAnimate}" sollte geändert werden in: [ngClass]="{'show': visibleAnimate}"

Um dies zu demonstrieren, hier ein plunkr

195
Stephen Paul

Hier ist ein gutes Beispiel dafür, wie Sie das Bootstrap-Modal in einer Angular2-App unter GitHub verwenden können.

Das Wichtigste dabei ist, dass Sie die Bootstrap-HTML- und Jquery-Initialisierung in eine Komponente einbetten können. Ich habe eine wiederverwendbare modal-Komponente erstellt, mit der Sie mithilfe einer Vorlagenvariablen ein Öffnen auslösen können.

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

Sie müssen lediglich das npm-Paket installieren und das modale Modul in Ihrem App-Modul registrieren:

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

@NgModule({
    imports: [Ng2Bs3ModalModule]
})
export class MyAppModule {}
55
Douglas Ludlow

Dies ist ein einfacher Ansatz, der nicht von Jquery oder einer anderen Bibliothek mit Ausnahme von Angular 2 ..__ abhängt. Die folgende Komponente (errorMessage.ts) kann als untergeordnete Ansicht einer anderen Komponente verwendet werden. Es ist einfach ein Bootstrap-Modal, der immer geöffnet oder gezeigt ist. Ihre Sichtbarkeit wird durch die ngIf -Anweisung geregelt.

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>

Dies ist ein Beispiel für ein übergeordnetes Steuerelement (einige nicht relevante Codes wurden der Kürze halber weggelassen):

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...
45
Sam

Jetzt als NPM-Paket verfügbar

Winkel-Custom-Modal


@Stephen Paul Fortsetzung ...

  • Angular 2 und höher Bootstrap css (Animation bleibt erhalten)
  • NO JQuery 
  • NO bootstrap.js
  • Unterstützt benutzerdefinierten modalen Inhalt
  • Unterstützung für mehrere Modale über jedem Anderen.
  • Moduralisiert
  • Scroll deaktivieren, wenn Modal geöffnet ist
  • Modal wird beim Navigieren zerstört.
  • Lazy-Inhaltsinitialisierung, die beim Verlassen des Modals ngOnDestroy (ed) erhält.
  • Parent-Scrolling deaktiviert, wenn Modal sichtbar ist

Faule Inhaltsinitialisierung

Warum?

In einigen Fällen möchten Sie möglicherweise nicht modal, um den Status nach dem Schließen beizubehalten, sondern müssen den ursprünglichen Status wiederherstellen.

Ursprüngliche modale Ausgabe

Wenn Sie den Inhalt direkt in die Ansicht übergeben, wird er initialisiert, noch bevor der Modal ihn erhält. Der Modal kann diesen Inhalt nicht beenden, selbst wenn er einen *ngIf-Wrapper verwendet.

Lösung

ng-template. ng-template wird erst gerufen, wenn er dazu aufgefordert wird.

meine-komponente.module.ts

...
imports: [
  ...
  ModalModule
]

meine-komponente.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>

Verweise

Ich muss sagen, dass es ohne die ausgezeichneten offiziellen und Community-Dokumentationen im Netz nicht möglich gewesen wäre. Es kann für einige von Ihnen auch hilfreich sein, die Funktionsweise von ng-template, *ngTemplateOutlet und @ContentChild besser zu verstehen.

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

Vollständige Copy-Paste-Lösung

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 { }
9
zurfyx

Ich benutze ngx-bootstrap für mein Projekt.

Sie finden die Demo hier

Der Github ist hier

Wie benutzt man:

  1. Installiere ngx-bootstrap

  2. Importieren Sie in Ihr Modul

// 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. Einfacher statischer Modal
<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>
7
Frank Nguyen

Hier ist meine vollständige Implementierung der modalen Bootstrap-Komponente angle2:

Ich gehe davon aus, dass Sie in Ihrer index.html -Datei (mit <html>- und <body>-Tags) am unteren Ende des <body>-Tags

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

Und ein Beispiel für die Verwendung in der Client-Editor-Komponente: 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>

Natürlich title, showClose, <mhead> und <mfoot> sind optionale Parameter/Tags.

4

Prüfen Sie den ASUI-Dialog, den Sie zur Laufzeit erstellen. Es ist keine Logik zum Verstecken und Zeigen erforderlich. Simply Service erstellt eine Komponente zur Laufzeit mit AOT ASUI NPM

2
Aravind Sivam

Angular 7 + NgBootstrap

Eine einfache Möglichkeit, Modal von der Hauptkomponente aus zu öffnen und das Ergebnis an sie weiterzugeben. ist was ich wollte. Ich habe ein Schritt-für-Schritt-Tutorial erstellt, das das Erstellen eines neuen Projekts von Grund auf, das Installieren von ngbootstrap und das Erstellen von Modal umfasst. Sie können es entweder klonen oder der Anleitung folgen. 

Hoffe, das hilft neu bei Angular!

https://github.com/wkaczurba/modal-demo

Einzelheiten:

modal-simple Vorlage (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">&times;</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>

Die 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() {
  }

}

Demo davon (app.component.html) - einfache Art und Weise, mit dem Ereignis "return" umzugehen: 

<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 wird ausgeführt, sobald Modal geschlossen wird:

@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;
  }    
}

Prost

0
Witold Kaczurba

versuchen Sie, ng-window zu verwenden, damit Entwickler mehrere Fenster in Einzelseitenanwendungen auf einfache Weise öffnen und steuern können.

 enter image description here

Verfügbare Konfiguration

  • Maximales Fenster
  • Fenster minimieren
  • Benutzerdefiniertes Format,
  • Benutzerdefinierte Position
  • das Fenster ist ziehbar 
  • Übergeordnetes Fenster blockieren oder nicht
  • Fenster zentrieren oder nicht
  • Übergeben Sie die Werte an das Chield-Fenster 
  • Übergeben Sie die Werte vom Feld "Fenster" an das übergeordnete Fenster
  • Schließen des Chield-Fensters im übergeordneten Fenster
  • Hören Sie die Größenänderung des Ereignisses mit Ihrem benutzerdefinierten Listener
  • Mit maximaler Größe öffnen oder nicht
  • Aktivieren und deaktivieren Sie die Fenstergröße
  • Aktivieren und deaktivieren Sie die Maximierung
  • Minimierung aktivieren und deaktivieren
0
Bahgat Mashaly