使用angular2 / 4 App中的服务和eventEmitters在组件之间共享模态

时间:2017-06-02 10:10:49

标签: angular modal-dialog eventemitter

我是angular2 / 4的新手。我想用动态的主体和页脚构建共享模态,然后监听用户按下的页脚的哪个按钮。我被@echonax在plunker中的贡献所激励,我将其编辑为follows。我将按钮绑定到eventEmitters

模板:

<div class="modal fade" id="theModal" tabindex="-1" role="dialog" aria-labelledby="theModalLabel">
  <div class="modal-dialog largeWidth" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title" id="theModalLabel">The Label</h4>
      </div>
      <div class="modal-body" #theBody>
      </div>
      <div class="modal-footer">
        <button class="btn btn-primary" (click)="submit()">save</button>
        <button class="btn btn-primary" (click)="edit()">edit</button>
        <button type="button" class="btn btn-default">Close</button>
      </div>
    </div>
  </div>
</div>

组件:

@Output() modalOutput: EventEmitter = new EventEmitter();

edit() {
  if (this.cmpRef) {
      this.cmpRef.destroy();
  }
  this.cmpRef = null;
  $('#theModal').modal('hide');
  this.modalOuput.emit('edit');
}  

submit() {
  if (this.cmpRef) {
     this.cmpRef.destroy();
  }
  this.cmpRef = null;
  $('#theModal').modal('hide');
  this.modalOuput.emit('submit');
}

并在index.html中:

<modal-comp (modalOutput)="modalData($event)"></modal-comp>

我使用eventEmitter来捕获按下的按钮,但我不知道如何从启动模式的组件中听取该事件。

1 个答案:

答案 0 :(得分:1)

我们提出的解决方案如下: 创建一个处理模态事件的共享服务(单击模式按钮时显示,隐藏和回调),然后通过传递自定义回调(以及为什么不是自定义模式体)从任何组件调用该服务。 模态组件:

  export class ModalComponent {
  @ViewChild('theBody', {read: ViewContainerRef}) theBody;
  cmp:ComponentRef;
  data;

  constructor(
    private sharedService:SharedService, 
    private componentFactoryResolver: ComponentFactoryResolver, 
    injector: Injector) {

    sharedService.modalEvents.subscribe(data => {
      console.log("data", data);
      this.data = data.data;
      if(data.cmd == "show"){
        if(this.cmpRef) {
          this.cmpRef.destroy();
        }
        let factory = this.componentFactoryResolver.resolveComponentFactory(data.component);
        this.cmpRef = this.theBody.createComponent(factory)
        $('#theModal').modal('show');
      }else{
        this.dispose();
      }

    });
  }

   close() {
        //this.dispose();
        this.sharedService.hideModal(true, this.data);
    }

    dispose() {
        if (this.cmpRef) {
            this.cmpRef.destroy();
        }
        this.cmpRef = null;
        $('#theModal').modal('hide');
    }
  edit() {
    this.dispose();
     this.sharedService.modalEvents.next("edit");
  }

  submit() {
    this.dispose();
    this.sharedService.modalEvents.next("submit");
  }
}

和共享服务:

@Injectable()
export class SharedService {

  modalEvents: Subject = new Subject();

  popupData;
  hasModalShown;

  showModal(component:any, data?:any, callback?:any, cancelCallback?:any)  {
        //this.showModal.next(component);

        var innerFunc = ()=> {
            this.popupData = {cmd: "show", component: component, data: data,
            callback: callback, cancelCallback: cancelCallback };
            this.modalEvents.next(this.popupData);
            this.hasModalShown = true;
        }

        if (this.hasModalShown) {
            this.hideModal();
            //setTimeout(innerFunc,600);
        } else {
            innerFunc();
        }
    }

    hideModal(isSubmit:boolean=false, data?:any) {
        if (this.hasModalShown) {
            this.modalEvents.next({cmd: "hide"});
            if(isSubmit && this.popupData.callback){
              this.popupData.callback(data);
            }else if(this.popupData.cancelCallback){
              this.popupData.cancelCallback(data);

            }

            this.hasModalShown = false;
        }
    }
}

这是plunker

中的一个工作示例