我正在构建一个模式,提供一个服务来打开和关闭它。该模态有一个控制关闭按钮的小控制器,以及进入模态内容的模板的$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 :(得分: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;