web-dev-qa-db-fra.com

ngx-bootstrap modal: Comment obtenir une valeur de retour d'un modal?

Dans mon application Angular 4, supposons que je suis dans un service.

À un moment donné, je souhaite demander une confirmation à l'utilisateur. Pour le moment, je le fais uniquement avec une requête confirm(...):

const result = confirm('Are you sure?');

et si au lieu de cela je voudrais montrer un ngx-bootstrap modal avec, disons, deux boutons "Oui" ou "Non" et obtenir un résultat similaire?


EDIT: dans mon cas, j'ai résolu mon problème en jouant avec Subjects. Ici vous pouvez trouver ma solution, au cas où elle pourrait être utile à quelqu'un d'autre. Cependant, cette solution ne résout pas this la question qui consiste à renvoyer une valeur depuis un modal, je la laisse donc ouverte.

18
Francesco Borzi

Essayez comme ça: 

mon exemple cela fonctionne correctement. J'espère que ceci vous aidera

home.module.ts

import { ModalModule } from 'ngx-bootstrap';

@NgModule({
    imports: [
        ModalModule.forRoot()
    ]
})

home.component.html

<button class="btn btn-primary" (click)="openConfirmDialog()">Open Confirm box</button>

home.component.ts

import { BsModalService } from 'ngx-bootstrap/modal';
import { BsModalRef } from 'ngx-bootstrap/modal/modal-options.class';

export class HomeComponent {
    public modalRef: BsModalRef;
    constructor(
        private homeService: HomeService,
        private modalService: BsModalService
    ) { }

    openConfirmDialog() {
        this.modalRef = this.modalService.show(HomeModalComponent);
        this.modalRef.content.onClose.subscribe(result => {
            console.log('results', result);
        })
    }
}

home-modal.component.html

<div class="alert-box">
    <div class="modal-header">
        <h4 class="modal-title">Confirm</h4>
        <button type="button" class="close" aria-label="Close" (click)="bsModalRef.hide()">
            <span aria-hidden="true">&times;</span>
        </button>
    </div>
    <div class="modal-body">
        Are you sure want to delete this node?
    </div>
    <div class="modal-footer">
        <button type="button" class="btn btn-secondary" (click)="onConfirm()">Yes</button>
        <button type="button" class="btn btn-secondary" (click)="onCancel()">No</button>        
    </div>
</div>

home-modal.component.ts

import { Subject } from 'rxjs/Subject';
import { BsModalRef } from 'ngx-bootstrap/modal';

export class HomeModalComponent {

    public onClose: Subject<boolean>;

    constructor(private _bsModalRef: BsModalRef) {

    }

    public ngOnInit(): void {
        this.onClose = new Subject();
    }

    public onConfirm(): void {
        this.onClose.next(true);
        this._bsModalRef.hide();
    }

    public onCancel(): void {
        this.onClose.next(false);
        this._bsModalRef.hide();
    }
}
54
Chandru

J'ai utilisé la solution de @Chandru, mais pour retourner a true ou false, au lieu de:

openConfirmDialog() {
    this.modalRef = this.modalService.show(HomeModalComponent);
    this.modalRef.content.onClose.subscribe(result => {
        console.log('results', result);
    })
}

J'ai simplement utilisé:

openConfirmDialog() {
    this.modalRef = this.modalService.show(HomeModalComponent);
    return this.modalRef.content.onClose;
}
3
Chris Halcrow

@ShinDarth Vous pouvez ajouter cette fonction à votre service et appeler cette fonction à tout moment.

Dans votre service, créez cette fonction

    openConfirmDialogBox() {
        this.modalRef = this.modalService.show(DemoModalComponent);
        this.modalRef.content.action.take(1)
            .subscribe((value) => {
                console.log(value) // here value passed on clicking ok will be printed in console. Here true will be printed if OK is clicked
                return value;
             }, (err) => {
                 return false;
        });
    }

Dans votre démo-modal.component.ts, créez un EventEmitter 

 @Output() action = new EventEmitter();
 public onClickOK() {
    this.action.emit(true); //Can send your required data here instead of true
 }
 public onClickCANCEL() {
    this.action.emit(false); //Can send your required data here instead of true
 }

J'espère que cela vous aiderait 

1
khush

Je comprends que la plupart des réponses ci-dessus sont tout à fait valables, mais que l’objectif principal est de pouvoir appeler la boîte de dialogue de confirmation de cette façon ...

  async openModalConfirmation() {
    const result = await this.confirmationSvc.confirm('Confirm this...');
    if (result) {
      console.log('Yes!');
    } else {
      console.log('Oh no...');
    }
  }

Notez que ceci est principalement du sucre syntaxique pour simplifier l'utilisation d'une promesse et des éléments asynchrones.

Je pense que c'est ce que l'OP cherchait et peut probablement être retravaillé pour permettre la restitution de tout autre type de données (à l'exception d'un booléen).

Le reste du code ci-dessous (sans compter le modèle pour rester bref), assez simple ..

ModalConfirmationService

import { ModalConfirmationComponent } from './component';

@Injectable()
export class ModalConfirmationService {

  constructor(private bsModalService: BsModalService) {}

  confirm(message: string): Promise<boolean> {
    const modal = this.bsModalService.show(ModalConfirmationComponent, { initialState: { message: message }});

    return new Promise<boolean>((resolve, reject) => modal.content.result.subscribe((result) => resolve(result) ));
  }
}

ModalConfirmationComponent  

import { Component, Input, Output, EventEmitter} from '@angular/core';
import { BsModalRef } from 'ngx-bootstrap/modal/bs-modal-ref.service';
import { Subject } from 'rxjs/Subject';

@Component({
  templateUrl: './component.html'
})
export class ModalConfirmationComponent {
  @Input() message: string;
  result: Subject<boolean> = new Subject<boolean>();

  constructor(public modalRef: BsModalRef) { }

  confirm(): void {
    this.result.next(true);
    this.modalRef.hide();
  }

  decline(): void {
    this.result.next(false);
    this.modalRef.hide();
  }
}
0
agascon

Essayez avec l'option ci-dessous qui fonctionne pour moi . CallbackOnModelWindowClose est la valeur de retour.

@Output() callbackOnModelWindowClose: EventEmitter<null> = new EventEmitter();

const initialState = {
          isModelWindowView: true, bodyStyle: 'row', gridDataList: this.scheduleList
        };

this.modalRef = this.modalService.show(YourComponent,
          Object.assign({}, this.modalConfig, { class: 'modal-dialog-centered', initialState });

this.modalRef.content.callbackOnModelWindowClose.take(1).subscribe(() => {
            your code here..
          });
0
Vijay Kesanupalli