2016-08-11 3 views
0

Я создаю модальный, который предоставляет услугу для включения и выключения. У этого модала есть небольшой контроллер, который управляет кнопкой закрытия, и $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; 

ответ

0

Aha! Оказывается, это не так сложно. Вам просто нужно сохранить область действия компонента, а затем вызвать $ 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;