简体   繁体   English

ngx-bootstrap modal:如何从模态中获取返回值?

[英]ngx-bootstrap modal: How to get a return value from a modal?

In my Angular 4 app, let's assume that I'm inside a service.在我的 Angular 4 应用程序中,假设我在一个服务中。

At some point, I want to ask the user for a confirmation, currently I'm doing it with just a confirm(...) request:在某些时候,我想要求用户进行确认,目前我只是通过一个confirm(...)请求来做到这一点:

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

What if instead I would like to show an ngx-bootstrap modal with, let's say, two buttons "Yes" or "No" and obtain a similar result?相反,如果我想显示一个ngx-bootstrap模态,比如说,两个按钮“是”或“否”并获得类似的结果怎么办?


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.然而,该解决方案并没有解决这个问题,即从模态返回一个值,所以我让它保持打开状态。

Try like this :像这样尝试:

myexample it's working correctly.我的例子它工作正常。 hope this will help you希望这会帮助你

home.module.ts home.module.ts

import { ModalModule } from 'ngx-bootstrap';

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

home.component.html主页.component.html

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

home.component.ts 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 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 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();
    }
}

I used the solution from @Chandru, however to return a true or false , instead of:我使用了@Chandru 的解决方案,但是返回一个truefalse ,而不是:

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

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.请注意,这主要是语法糖,用于简化 promise 和异步内容的使用。

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).我认为这是 OP 正在寻找的,并且可能可以重新设计以支持返回任何其他数据类型(布尔值除外)。

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

@ShinDarth You can add this function in your service and call this funcion whenever required. @ShinDarth 您可以在您的服务中添加此功能,并在需要时调用此功能。

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在您的 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
 }

I hope this would help you我希望这会帮助你

Try this:试试这个:

home.component.ts 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);
     })
 }
}

and

home-modal.component.ts home-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();
 }
}

If you are using a later version of Angular you might get an error due to the location of BsModalRef that had moved:如果您使用的是更高版本的 Angular,您可能会由于 BsModalRef 的位置移动而收到错误:

Use this location:使用这个位置:

import { BsModalRef } from 'ngx-bootstrap/modal/bs-modal-ref.service';

rather than:而不是:

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

I do not know if that suits you, but I used a service with Subject.我不知道这是否适合您,但我使用了 Subject 的服务。 In parent component it is enough to subscribe and unsubscribe, in modal component, when user clicks confirm button, then just emit value using next.在父组件中订阅和取消订阅就足够了,在模态组件中,当用户单击确认按钮时,只需使用 next 发出值。

I'm sorry for not presenting a full example, but pseudocode below should present the idea.我很抱歉没有提供完整的示例,但下面的伪代码应该可以表达这个想法。

Service:服务:

export class SomeService{
    yourSubject: new Subject<string>();
}

Parent component:父组件:

...
ngOnInit(){
    this.bsModalRef = this.someService.yourSubject.subscribe ( val => ...);
}
ngOnDestroy(){
    this.bsModalRef.unsubscribe();
}
...

Modal component:模态组件:

...
onSaveAction(){
    this.someService.yourSubject.next(val);
}
...

Ps.附言。 of course you need to provide service in proper place and inject it into components :-)当然,您需要在适当的位置提供服务并将其注入组件:-)

Try with below option which is working for me.尝试使用以下对我有用的选项。 callbackOnModelWindowClose is the return value. 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..
          });

Try this!!!!试试这个!!!! Create modal options with a yes function and a no function in the options.使用选项中的 yes 函数和 no 函数创建模态选项。 Receive args as @Input...接收参数为@Input...

import { Component, OnInit, Input } from '@angular/core';
import { BsModalRef } from 'ngx-bootstrap/modal';

@Component({
    selector: 'confirm-box',
    templateUrl: './confirm-box.component.html',
    styleUrls: ['./confirm-box.component.css']
})
export class ConfirmBoxComponent implements OnInit {
    private _args: any;

    public get args(): any {
        return this._args;
    }

    @Input()
    public set args(value: any) {
        this._args = value;
    }

    constructor(private activeModal: BsModalRef) {
    }

    ngOnInit(): void {
    }

    public no(): void {
        this.args.noFunction();
        this.activeModal.hide();
    }

    public yes(): void {
        this.args.yesFunction();
        this.activeModal.hide();
    }
}

And then the component or service that launches the dialog:然后是启动对话框的组件或服务:

import { BsModalService, BsModalRef, ModalOptions } from 'ngx-bootstrap/modal';
import { ConfirmBoxComponent } from '../../dialogs/confirm-box/confirm-box.component';

export class AreYouSure {    
    private activeModal: BsModalRef;

    constructor(private modalService: BsModalService) {
          //Wait five seconds before launching the confirmbox
          setTimeout(()=>{
             this.tryLaunchConfirm();
          }, 5000);
    }
    private tryLaunchConfirm(): void {
        const config: ModalOptions = {
            initialState: {
                args: {
                    title: "Confirm This",
                    message: "Are you really sure???",
                    yesFunction: () => { console.log("YES!!!! was clicked."); },
                    noFunction: () => { console.log("NO!!!! was clicked."); }
                }
            }
        }
        this.activeModal = this.modalService.show(ConfirmBoxComponent, config);

    }
}


声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM