我有一个应用程序,因为我需要模拟os窗口类型的行为。所以我需要能够添加多个窗口,每个窗口都有自己的上下文,可能还有自己的嵌套指令。
我已经有了windowDirective和userProfile指令,我想实例化每个指针的新实例并根据需要添加它或从dom中删除它。
到目前为止,我尝试用一个WindowService来实现这个目的,使用$ compile来实质上编译一个带有指令标记的字符串,即$compile("<window><user-profile></user-profile></window>")(scope)
,这似乎创建了一个dom树,但却出现了一堆错误。
关于我如何处理此事的任何想法?
答案 0 :(得分:1)
我做了类似的事情。
对于初学者,您需要创建一个指令,该指令将成为您的主要容器(用于放置在其中的其他窗口)。将控制器分配给该主容器,该容器将保留您计划插入/移除的所有其他子窗口的列表。无论何时想要销毁范围和内存,都需要这样做。
var module = angular.module('myModule', []);
module.directive('myContainer', ContainerDirective);
function ContainerDirective() {
return {
restrict: 'E',
controller: ['$scope', '$element', '$compile', function ContainerController($scope, $element, $compile) {
var winId = 0;
this.subWindows = {};
//Create a window
this.createWindow = function() {
var subWinElem = angular.element('<my-window>');
this.subWindows[winId++] = subWinElem;
$element.append(subWinElem);
$compile(subWinElem)(scope);
subWinElem.data('window-id', winId);
return winId;
};
//Destroy a window
this.destroyWindow = function(winId) {
if(this.subWindows[winId]) {
var subWinElem = this.subWindows[winId],
subWinScope = subWinElem.scope();
subWinElem.remove();
subWinScope.$destoroy();
this.subWindows[winId] = null;
}
};
//Clean up on container destroy
this.dispose = function() {
angular.forEach(this.subWindows, function(subWinElem) {
if(subWinElem) {
var subWinScope = subWinElem.scope();
subWinElem.remove();
subWinScope.$destroy();
}
});
};
}],
link: function($scope, elem, attrs, ContainerController) {
//On click of a button you would create a sub window
scope.createWindow = function() {
ContainerController.createWindow();
};
//Cleanup anything left in the controller
$scope.$on('$destroy', function() {
ContainerController.dispose();
});
}
};
}
子窗口应该是“需要”父控制器的指令。要动态调用它们,你可以做的是首先附加指令标记然后$编译对该元素的引用(比$ compile('string')好得多)。因为你首先追加元素然后编译你,能够没有问题地要求父控制器(因为它使用inheritedData)。
module.directive('myWindow', WindowDirective);
function WindowDirective() {
return {
restrict: 'E',
scope: true,
require: '?^myContainer',
link: function($scope, elem, attrs, ContainerController) {
var winId = elem.data('window-id');
//You would destroy window like so
$scope.$on('$destroy', function() {
ContainerController.destroyWindow(winId);
});
}
}
}
P.S。这是一个非常简单的例子(可能包含拼写错误:P),但你得到了它的要点。