Açısal 2.0 ve Modal İletişim Kutusu


128

Angular 2.0'da Confirmation modal dialogun nasıl yapılacağına dair bazı örnekler bulmaya çalışıyorum. Angular 1.0 için Bootstrap iletişim kutusunu kullanıyorum ve Angular 2.0 için web'de herhangi bir örnek bulamıyorum. Ayrıca açısal 2.0 dokümanları da şanssız olarak kontrol ettim.

Angular 2.0 ile Bootstrap iletişim kutusunu kullanmanın bir yolu var mı?


Bu örneği buldum. Belki size yardımcı olur angularscript.com/angular2-modal-window-with-bootstrap-style
Puya Sarmidani

1
Bunu RC3 ile kullanıyorum ve oldukça memnunum
mentat

@ Sam sayesinde iyi bir başlangıç ​​yaptım. Ancak, arayan bileşenin hangi düğmenin tıklandığını bilmediğini fark ettim. Biraz araştırdıktan sonra, daha zarif bir çözüm bulmak için EventEmitters yerine Observables'ı kullanabildim .
Jon


Yanıtlar:


199
  • Açısal 2 ve üstü
  • Bootstrap css (animasyon korunur)
  • JQuery YOK
  • NO bootstrap.js
  • Özel kalıcı içeriği destekler (kabul edilen cevap gibi)
  • Son zamanlarda birden fazla mod için üst üste destek eklendi .

'

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

Arka planı göstermek için şu CSS gibi bir şeye ihtiyacınız olacak:

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

Örnek artık aynı anda birden fazla kipe izin vermektedir . ( onContainerClicked()yönteme bakın ).

Bootstrap 4 css kullanıcıları için için 1 küçük değişiklik yapmanız gerekir (çünkü Bootstrap 3'ten bir css sınıf adı güncellendi). Bu satır: [ngClass]="{'in': visibleAnimate}"şu şekilde değiştirilmelidir: [ngClass]="{'show': visibleAnimate}"

Göstermek için, işte bir plunkr


Yine de bir sorun var. Düğmeler burada fazladan bir öğenin içine sarıldığı için, önyükleme stili düğmelere kenar boşlukları uygulamaz (en azından v4'te). sargıyı çıkarmak div.modal-footerve olarak değiştirmek .app-modal-footerbunu .modal-footerdüzeltir.
Axel Köhler

55

İşte bir Angular2 uygulamasında Bootstrap modelini nasıl kullanabileceğinize dair oldukça iyi bir örnek. GitHub'daki .

İşin özü, bootstrap html ve jquery başlatmayı bir bileşene sarabilmenizdir. modalBir şablon değişkeni kullanarak bir açmayı tetiklemenize olanak tanıyan yeniden kullanılabilir bir bileşen oluşturdum .

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

Sadece npm paketini kurmanız ve modal modülü uygulama modülünüze kaydetmeniz yeterlidir:

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

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

8
Bummer - bağımlılık olarak jquery'ye güveniyor :(
brando

52
Evet, bootstrap buna güveniyor ve ben kütüphaneleri yeniden yazma işinde değilim.
Douglas Ludlow

2
Bu jQuery olmadan yapılabilir. Sam'in cevabını koscielniak.me/post/2016/03/angular2-confirm-dialog-component adresindeki öğretici ile birlikte bir hizmet ve ilgili modal bileşen yazmak için kullandım.
BeetleJuice

Projenizde bootstrap kullanmıyorsanız, bootstrap.css'ye link eklemeyi unutmayın. Github sayfası bundan bahsetmeyi unutuyor.
Shekhar

46

Bu, jquery'ye veya Angular 2 dışında herhangi bir kitaplığa bağlı olmayan basit bir yaklaşımdır. Aşağıdaki bileşen (errorMessage.ts), başka herhangi bir bileşenin alt görünümü olarak kullanılabilir. Her zaman açık veya gösterilen basit bir önyükleme modelidir. Görünürlüğü ngIf ifadesiyle yönetilir.

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>

Bu örnek bir ebeveyn kontrolüdür (ilgili olmayan bazı kodlar kısalık olması için çıkarılmıştır):

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

3
güzel - açıklayabilirimclass="modal fade show in danger"
bensiu

@bensiu Sınıf seçicinin kullanılmadığını tahmin ediyorum - tüm bu kelimeler için bir css stil seçicileri yoksa, örneğin 'in'
Drenai

Bununla fade in / out etkisini nasıl elde edersiniz?
Big McLargeHuge

10

Şimdi bir NPM paketi olarak mevcut

açısal özel modal


@Stephen Paul devamı ...

  • Angular 2 ve üstü Bootstrap css (animasyon korunur)
  • JQuery YOK
  • NO bootstrap.js
  • Özel kalıcı içeriği destekler
  • Üst üste birden çok mod desteği.
  • Moduralized
  • Modal açıkken kaydırmayı devre dışı bırak
  • Modal uzaklaşırken yok oluyor.
  • Modaldan ngOnDestroyçıkıldığında alınan (düzenlenen) tembel içerik başlatma .
  • Modal göründüğünde üst kaydırma devre dışı bırakıldı

Geç içerik başlatma

Neden?

Bazı durumlarda, kapatıldıktan sonra durumunu korumak için modal yapmak istemeyebilirsiniz, bunun yerine başlangıç ​​durumuna geri dönebilirsiniz.

Orijinal mod sorunu

İçeriğin doğrudan görünüme aktarılması, aslında onu modal almadan önce bile başlatır. Modal, bir *ngIfsarmalayıcı kullanıyor olsa bile bu tür içeriği öldürmenin bir yolunu bulamaz.

Çözüm

ng-template. ng-templatesipariş edilene kadar işlemez.

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>

Referanslar

İnternetin etrafındaki mükemmel resmi ve topluluk belgeleri olmadan bunun mümkün olmayacağını söylemeliyim. Bazılarınız çok daha iyi anlamak için yardımcı olabilir ng-template, *ngTemplateOutletve @ContentChildçalışması.

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

Tam kopyala-yapıştır çözümü

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

7

Projem için ngx-bootstrap kullanıyorum .

Demoyu burada bulabilirsiniz

GitHub burada

Nasıl kullanılır:

  1. Ngx-bootstrap'i yükleyin

  2. Modülünüze aktarın

// 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. Basit statik 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>

4

İşte modal bootstrap angular2 bileşeninin tam uygulaması:

Ana index.html dosyanızda ( <html>ve <body>etiketleri ile) <body>etiketinin altında olduğunu varsayıyorum :

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

İstemci Düzenleyici bileşenindeki kullanım örneği: 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();
    }

}

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

Tabii title, showClose, <mhead>ve <mfoot>isteğe bağlı parametreleri / etiketleri ar.


2
Yerine bindModal(modal) {this._modal=modal;}, sen açısal en kullanabilirsiniz ViewChildşöyle, ek açıklama: @ViewChild('editModal') _modal: Modal;. Perde arkasında sizin için bağlamayı halleder.
Douglas Ludlow


0

ng-penceresini kullanmayı deneyin, geliştiricinin tek sayfalı uygulamalarda birden fazla pencereyi basit bir şekilde açmasına ve tam kontrol etmesine izin verir, Jquery Yok, Önyükleme Yok.

görüntü açıklamasını buraya girin

Avilable Configration

  • Maxmize penceresi
  • Pencereyi küçült
  • Özel boyut,
  • Özel konum
  • pencere sürüklenebilir
  • Ana pencereyi engelle ya da engelleme
  • Pencereyi ortalayın ya da ortalamayın
  • Değerleri chield penceresine geçirme
  • Chield penceresinden ana pencereye değer geçirme
  • Üst pencerede oda penceresini kapatmayı dinleme
  • Özel dinleyicinizle etkinliği yeniden boyutlandırmayı dinleyin
  • Maksimum boyutta aç veya aç
  • Pencere yeniden boyutlandırmayı etkinleştirin ve devre dışı bırakın
  • Maksimizasyonu etkinleştirin ve devre dışı bırakın
  • Küçültmeyi etkinleştirin ve devre dışı bırakın

-1 Bu nasıl yararlı olur? OP tarafından belirtilen gerekliliklerin hiçbirine hitap etmez. Bu 4. gönderi senin cevabını trollediğini görüyorum
avn

0

Açısal 7 + NgBootstrap

Modeli ana bileşenden açmanın ve sonucu ona geri göndermenin basit bir yolu. istediğim buydu. Sıfırdan yeni bir proje oluşturmayı, ngbootstrap'i kurmayı ve Modal oluşturmayı içeren adım adım bir eğitim oluşturdum. Ya klonlayabilir ya da kılavuzu takip edebilirsiniz.

Umarım bu, Angular'da yenidir.

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

Detaylar:

modal-basit şablon (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>

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

}

Demosu (app.component.html) - dönüş olayıyla başa çıkmanın basit yolu:

<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, modal kapatıldıktan sonra yürütülür:

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

Şerefe

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.