美文网首页angular2.0
如何实现angular2版本的modal弹框

如何实现angular2版本的modal弹框

作者: 前端大魔王 | 来源:发表于2018-01-25 19:30 被阅读416次

    最近看angular2项目代码时发现项目中modal的使用形式是,哪里需要modal就写在哪里,modal嵌入在Dom树中的很深层而不是在直接挂在body下,这样会导致很大的问题。产生问题原因可以产看该链接:http://web.jobbole.com/92121/

    于是就想自己写一个能直接在挂在body底下的modal。

    那么怎么实现能?通过传统component,其存在于component树中显然无法随意改变component在树中的结构,好在我们有dynamic component,通过它我们能自主创建其实例并自主决定其挂载的位置,比如我们要挂载至body下。

    具体实现如下,为了图方便自己基于jquery和bootstrap3实现(基于原生实现原理相同),原理:动态实例化组件,将组件dom挂至body下。删除时destroy component ,移除dom

    import {
      ComponentFactoryResolver,
      ComponentRef,
      ReflectiveInjector,
      ApplicationRef,
      Injectable,
      EventEmitter,
    } from '@angular/core';
    @Injectable()
    export class ModalService {
      private modals: Modal[] = [];
      constructor(private componentFactoryResolver: ComponentFactoryResolver,
                  private applicationRef: ApplicationRef) { }
    
      create(component) {
        const componentFactory = this.componentFactoryResolver.resolveComponentFactory(component);
        const injector = ReflectiveInjector.resolveAndCreate([]);
        const componentRef = componentFactory.create(injector);
        this.applicationRef.attachView(componentRef.hostView);
        document.body.appendChild(componentRef.location.nativeElement);
        const modal = new Modal(componentRef);
        this.modals.push(modal);
        return modal;
      }
      destory(modal: Modal) {
        modal.hide();
        this.modals.splice(this.modals.indexOf(modal), 1);
        modal.$el.remove();
        modal.componentRef.destroy();
      }
    }
    
    export class Modal {
      $el;
      $modalEl;
      public componentRef;
      public onShown = new EventEmitter();
      public onHidden = new EventEmitter();
      constructor(componentRef) {
        this.$el = $(componentRef.location.nativeElement);
        this.$modalEl = this.$el.find('.modal');
        this.componentRef = componentRef;
        this.$modalEl.on('shown.bs.modal', (e)=>{
          this.onShown.emit(e);
        });
        this.$modalEl.on('hidden.bs.modal',(e)=>{
          this.onHidden.emit(e);
        });
      }
      show() {
        this.$modalEl.modal('show');
      }
      hide() {
        this.$modalEl.modal('hide');
      }
    }
    

    使用

     this.modal = this.modal || this.modalService.create(SelectDeviceModalComponent);
        this.modal.show();
        this.modal.onHidden.subscribe((e) => {
          this.modalService.destory(this.modal);
          this.modal = null;
        });
    

    注意由于是基于bootstrap的实现所以。create中传的组件的html必须是bootstrap的modal形式,例如:

    <div class="modal fade" tabindex="-1" role="dialog" aria-labelledby="gridSystemModalLabel">
      <div class="modal-dialog" role="document">
        <div class="modal-content">
          <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            <h4 class="modal-title" id="gridSystemModalLabel">Modal title</h4>
          </div>
          <div class="modal-body">
           
          </div>
          <div class="modal-footer">
    
          </div>
        </div><!-- /.modal-content -->
      </div><!-- /.modal-dialog -->
    </div><!-- /.modal -->
    

    相关文章

      网友评论

        本文标题:如何实现angular2版本的modal弹框

        本文链接:https://www.haomeiwen.com/subject/khhbaxtx.html