我有一个由fancybox触发的模态窗口。当模态显示时,fancybox广播AppController侦听的“modalShown”事件。在该侦听器中,AppController对模态窗口的内容调用$ compile,以便在视图上创建ModalController,插入和绑定事件。
我的问题是,当我关闭模态时,模态元素将从DOM中删除,但其绑定的ModalController实例会在某处持久存在。所以每次打开一个新窗口时,我都会创建一个新的控制器,所有这些孤立的控制器都会响应模态窗口内的事件。
我的问题是,因为$ compile创建了新控制器,但没有返回对它的引用,如何清理在我的应用程序中传播的这些未使用的控制器?
相关代码(咖啡)......
Fancybox指令
# sets up the fancybox on each element that triggers the modal...
# <a href="#" fancybox="templateToLoad.html">Trigger Modal</a>
@app.directive 'fancybox', ["$templateCache", "$compile", ($templateCache, $compile) ->
(scope, element, attrs) ->
options =
afterShow : ->
scope.$root.$broadcast 'modalShown', scope
element.fancybox options
modal.html
<div class="fancybox-skin">
<div class="fancybox-outer">
<div class="fancybox-inner ng-scope">
<div ng-controller="ModalController" style="..." class="ng-scope">
<a href="#" ng-click="someAction()">Some Action in ModalController</a>
</div>
</div>
</div>
</div>
ModalController
app.controller 'ModalController', [
'$scope', '$rootScope',($scope, $rootScope) ->
# keeping track of controllers for debugging
window.globalCounter ||= 0
$scope.localCounter = window.globalCounter++
someAction = () ->
console.log 'action'
AppController的
@app.controller "AppController", [
"$scope", "$rootScope", "$compile", ($scope, $rootScope, $compile) ->
$scope.$on 'modalShown', (e, localScope) ->
console.log('compiling modal contents')
$compile($('.fancybox-inner'))(localScope)
$rootScope.$apply()
答案 0 :(得分:0)
你拥有的ModalController
实际上只是一个功能,可以在其相关$scope
上设置任何功能,然后再也不会看到或听到。您仍然看到的任何功能要么留在此范围内,要么从控制器泄漏,应该在$scope.$on('$destroy', function() { ... })
块中清除。
如果功能在范围内的$watch
es或$on
s中,那么当范围被销毁时,它们应该通过角度自动清除。如果它们仍然存在,那么当模态关闭时范围没有被销毁。
您正在使用$compile($('.fancybox-inner'))(localScope)
自行传递父作用域。如果您使用localScope
代替localScope.$new()
,那么当您看到模式关闭时,您就可以安全地在此新范围内调用.$destroy()
。
顺便说一句,我是否可以建议将AppController
功能移动到您的fancybox
指令中并完全避免这些广播 - DOM操作和编译在指令中比控制器更适合您,您可以更多轻松跟踪您需要创建的任何新范围。