【问题标题】:ngx-bootstrap modal: How to get a return value from a modal?ngx-bootstrap modal:如何从模态中获取返回值?
【发布时间】:2018-03-06 14:43:11
【问题描述】:

在我的 Angular 4 应用程序中,假设我在服务中。

在某些时候,我想要求用户确认,目前我只使用confirm(...) 请求:

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

如果我想显示一个ngx-bootstrap modal,比如说,两个按钮“是”或“否”并获得类似的结果,该怎么办?


编辑:就我而言,我通过玩主题解决了我的问题。 Here 你可以找到我的解决方案,以防它对其他人有用。但是,该解决方案不能解决 this 问题,即关于从模态返回值的问题,所以我将其保持打开状态。

【问题讨论】:

  • 到目前为止你有没有尝试过?
  • 在我的服务中,我可以使用this.modalService.show(this.confirmModal) 显示模态,但我不知道如何接收用户在模态中单击的结果
  • @ShinDarth 刚才只发布了我的答案.. 我希望这对你有用

标签: angular modal-dialog bootstrap-modal ngx-bootstrap confirm-dialog


【解决方案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);
        })
    }
}

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

【讨论】:

  • 感谢您的回答,但您将如何在服务中使用它?例如,在 Guard 的 CanDeactivate 方法中,它应该返回 true 或 false,无需等待?
  • 我需要用一个模态替换它:canDeactivate() { return confirm( 'are you sure?' ); } }
  • BsModalRef 路径已从 ngx-bootstrap/modal 更改为 ngx-bootstrap/modal/bs-modal-ref.service
  • @RezaRahmati,要自定义消息,您可以在 home-modal.component.html 中将 test 更改为 {{message}},然后像这样调用 show:const config = { message: 'Are you sure want to delete this node?'}; this.modalService.show(HomeModalComponent, { initialState: config });
  • 如果用户点击背景,在“openConfirmDialog”中订阅的主题会发生什么?
【解决方案2】:

我使用了@Chandru 的解决方案,但是返回truefalse,而不是:

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

    我知道上面的大部分答案都是完全有效的,但主要目标是能够以这种方式调用确认对话框......

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

    请注意,这主要是为了简化 Promise 和异步内容的使用的语法糖。

    我认为这是 OP 一直在寻找的,并且可能可以重新设计以支持返回任何其他数据类型(布尔值除外)。

    下面的其余代码(不包括保持简短的模板),非常简单..

    模态确认服务

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

    模态确认组件

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

    【讨论】:

      【解决方案4】:

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

      希望对你有帮助

      【讨论】:

        【解决方案5】:

        试试这个:

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

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

        【讨论】:

          【解决方案6】:

          如果您使用的是更高版本的 Angular,由于 BsModalRef 的位置已移动,您可能会收到错误:

          使用这个位置:

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

          而不是:

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

          【讨论】:

            【解决方案7】:

            我不知道这是否适合您,但我使用了 Subject 的服务。 在父组件中订阅和取消订阅就足够了,在模态组件中,当用户单击确认按钮时,然后使用 next 发出值。

            很抱歉没有提供完整的示例,但下面的伪代码应该可以说明这个想法。

            服务:

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

            父组件:

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

            模态组件:

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

            附言。当然,您需要在适当的位置提供服务并将其注入组件:-)

            【讨论】:

              【解决方案8】:

              尝试以下对我有用的选项。 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..
                        });
              

              【讨论】:

                【解决方案9】:

                试试这个!!!! 在选项中创建带有 yes 函数和 no 函数的模态选项。 接收 args 作为@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();
                    }
                }
                

                然后是启动对话框的组件或服务:

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

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2017-08-15
                  • 1970-01-01
                  • 2018-04-04
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-03-26
                  • 1970-01-01
                  • 2018-08-22
                  相关资源
                  最近更新 更多