【问题标题】:AngularJS $destroy dynamically inserted componentAngularJS $destroy 动态插入组件
【发布时间】:2016-12-18 09:43:19
【问题描述】:

我正在构建一个提供服务来打开和关闭它的模式。该模态有一个控制关闭按钮的小控制器,以及进入模态内容的模板的$compile

那个模板是一个组件,当然,那个组件有一个控制器。

隐藏模式后如何销毁该组件?从技术上讲,当 ng-if 负责从 DOM 中删除我的模式时,它仍然会加载该组件。

代码如下:

modal.controller.js

class ModalController {
  constructor($scope, modalService, $compile, $timeout) {
    this.$scope = $scope;
    this.modalService = modalService;
    this.$compile = $compile;
    this.$timeout = $timeout;
  }

  $onInit() {
    this.$scope.$watch(this.modalService.getConfig(), (newVal) => {
      this.config = newVal.isDisplayed
        ? angular.extend(this.config, newVal)
        : {};

      // I wait for ng-if to put the modal into the DOM then I 
      // compile the component.
      this.$timeout(() => {
        if (this.config.template) {
          const component = this.$compile(this.config.template)(this.$scope);
          angular.element('#modal-content').html(component);
          this.config.isRendered = true;
        }
      }, 0);
    }, true);
  }

  close() {
    this.modalService.close();
  }
}

ModalController.$inject = [
  '$scope',
  'modalService',
  '$compile',
  '$timeout',
];

export default ModalController;

modal.service.js

class ModalService {
  constructor($timeout) {
    this.config = {};
    this.$timeout = $timeout;
  }

  open(newConfig) {
    this.config = newConfig;
    this.config.isDisplayed = true;
  }

  close() {
    this.config.template = null;
    this.config.isRendered = false;

    // the reason there is timeout here is to run my CSS animation
    // before ng-if removes the modal from the DOM.
    this.$timeout(() => {
      this.config.isDisplayed = false;
      this.config = {};
    }, 310);
  }

  getConfig() {
    return () => this.config;
  }
}

ModalService.$inject = [
  '$timeout',
];

export default ModalService;

我调用模态的 BarController:

class BarController {
  constructor(modalService) {
    this.modalService = modalService;
  }

  openModal() {
    this.modalService.open({
      title: 'Add a document',
      template: '<foo-component></foo-component>',
    });
  }
}

BarController.$inject = [
  'modalService',
];

export default BarController;

【问题讨论】:

    标签: angularjs angular-components


    【解决方案1】:

    啊哈!事实证明,事情并没有那么复杂。你只需要存储组件的作用域,然后在模态控制器的close函数中调用$destroy即可。

    class ModalController {
      constructor($scope, modalService, $compile, $timeout) {
        this.$scope = $scope;
        this.modalService = modalService;
        this.$compile = $compile;
        this.$timeout = $timeout;
      }
    
      $onInit() {
        this.childScope = null;
    
        this.$scope.$watch(this.modalService.getConfig(), (newVal) => {
          this.config = newVal.isDisplayed
            ? angular.extend(this.config, newVal)
            : {};
    
          this.$timeout(() => {
            if (this.config.template) {
              this.childScope = this.$scope.$new();
    
              angular
                .element('#modal-content')
                .html(this.$compile(this.config.template)(this.childScope));
    
              this.config.isRendered = true;
            }
          }, 0);
        }, true);
      }
    
      close() {
        this.config.isRendered = false;
    
        // this timout is used to make sure the CSS transition is executed
        // before the component is removed from the DOM.
        this.$timeout(() => {
          this.childScope.$destroy();
          angular.element('#modal-content').empty();
          this.modalService.close();
        }, 310);
      }
    }
    
    ModalController.$inject = [
      '$scope',
      'modalService',
      '$compile',
      '$timeout',
    ];
    
    export default ModalController;
    

    【讨论】:

      猜你喜欢
      • 2017-05-29
      • 2015-03-21
      • 2017-03-27
      • 2019-04-24
      • 1970-01-01
      • 1970-01-01
      • 2016-12-16
      • 2019-12-08
      • 2017-06-08
      相关资源
      最近更新 更多