ngx-bootstrap modal: How to get a return value fro

2019-02-04 11:02发布

In my Angular 4 app, let's assume that I'm inside a service.

At some point I want to ask to the user for a confirmation, currently I'm doing it with just a confirm(...) request:

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

what if instead I would like to show a ngx-bootstrap modal with, let's say, two buttons "Yes" or "No" and obtain a similar result?


EDIT: in my case, I solved my issue by playing with Subjects. Here you can find my solution, in case it can be useful for someone else. However that solution does not solve this question which is about returning a value from a modal, so I leave it open.

5条回答
倾城 Initia
2楼-- · 2019-02-04 11:20

Try like this :

myexample it's working correctly. hope this will help you

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();
    }
}
查看更多
SAY GOODBYE
3楼-- · 2019-02-04 11:22

Try with below option which is working for me. callbackOnModelWindowClose is the return value.

@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..
          });
查看更多
时光不老,我们不散
4楼-- · 2019-02-04 11:28

@ShinDarth You can add this function in your service and call this funcion whenever required.

In your Service, create this function

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

In your demo-modal.component.ts, create an 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
 }

I hope this would help you

查看更多
Anthone
5楼-- · 2019-02-04 11:31

I used the solution from @Chandru, however to return a true or false, instead of:

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

I simply used:

openConfirmDialog() {
    this.modalRef = this.modalService.show(HomeModalComponent);
    return this.modalRef.content.onClose;
}
查看更多
我欲成王,谁敢阻挡
6楼-- · 2019-02-04 11:37

I understand that most of the answers above are completely valid, but that the main goal is be able to invoke the confirmation dialog in this way...

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

Note that this is mostly syntactic sugar to simplify the use of a promise and the asynchronous stuff.

I think it's what the OP was looking for and probably can be reworked to support returning any other data type (apart from a boolean).

The rest of the code below (not including the template to keep this short), pretty straightforward..

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();
  }
}
查看更多
登录 后发表回答