Ngx-bootstrap modal: Как получить возвращаемое значение из модального?

В моем приложении Angular 4 предположим, что я внутри службы.

В какой-то момент я хочу попросить пользователя подтвердить, в настоящее время я делаю это только с запросом confirm(...):

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

что, если вместо этого я хотел бы показать ngx-bootstrap модальный с, скажем, двумя кнопками "Да" или "Нет" и получить аналогичный результат?


EDIT: в моем случае я решил свою проблему, играя с темами. Здесь вы можете найти мое решение, если оно может быть полезно кому-то другому. Однако это решение не решает вопрос this, который заключается в возврате значения из модального, поэтому я оставляю его открытым.

Ответ 1

Попробуйте вот так:

myexample работает корректно. надеюсь, это поможет вам

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

домашняя 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>

дом-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();
    }
}

Ответ 2

Я использовал решение из @Chandru, однако, чтобы вернуть true или false вместо:

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

Я просто использовал:

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

Ответ 3

@ShinDarth Вы можете добавить эту функцию в свой сервис и вызывать эту функцию при необходимости.

В вашей службе создайте эту функцию

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

В вашем demo-modal.component.ts создайте 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
 }

Я надеюсь, что это поможет вам

Ответ 4

Я понимаю, что большинство из приведенных выше ответов полностью действительны, но главная цель - вызвать диалог подтверждения таким образом...

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

Обратите внимание, что это в основном синтаксический сахар, чтобы упростить использование обещаний и асинхронных вещей.

Я думаю, что это то, что ищет OP, и, вероятно, может быть переработано для поддержки возврата любого другого типа данных (кроме логического).

Остальная часть кода ниже (не включая шаблон для краткости), довольно проста.

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

Ответ 5

Попробуйте с опцией ниже, которая работает для меня. callbackOnModelWindowClose является возвращаемым значением.

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

Ответ 6

Попробуйте это:

home.component.ts

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

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

 openConfirmDialog() {
    this.modalRef = this.modalService.show(HomeModalComponent);

    this.modalRef.content.onClose = new Subject<boolean>();

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

и

дом-modal.component.ts

import { BsModalRef } from 'ngx-bootstrap/modal';
export class HomeModalComponent {

 constructor(private bsModalRef: BsModalRef) {

 }

 public ngOnInit(): void {
 }

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

 public onCancel(): void {
    this.bsModalRef.content.onClose.next(false);
    this.bsModalRef.hide();
 }
}