
本文介绍了AngularJS 不清理由 ng-include 创建的子作用域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有以下用例 - 我提供了一个对话服务,我根据上下文放置了不同的内容.在服务方法中,我手动编译了一个 dom 元素并使用它来显示使用 jquery ui 的对话框.代码如下:
var _view = jQuery('<div id="config-dialog"><span ng-include="\'' + $scope.configView + '\'" ng-controller="' + $scope.configController + '"></span></div>');var _compiled = $compile(_view.contents())($scope);
然后我触发一个范围事件,该事件应该由控制器中定义的范围函数处理
$scope.$broadcast('config-open', $scope.config);
然后我打开对话框,用户执行某些操作并关闭对话框.当对话框关闭时,我从 DOM 中删除了config-dialog"元素.像这样:
$(this).dialog("destroy");jQuery('#config-dialog').remove();
但是,下次打开对话框并实例化新控制器时,我看到config-open"被处理了两次,再次打开对话框时,它被处理了 3 次.这意味着附加到我动态创建的 ng-include 的范围不会被破坏.我已经用 Batarang 进行了调试,发现 ng-include 创建的子作用域确实没有被清除.AFAIK AngularJS 范围与 dom 元素相关联,当我删除该元素时,范围应该被垃圾收集,但这不会发生.我的问题是 - 在我的情况下,AngularJS 是否应该清理范围.我做错了什么,有没有更合适的方法来实现我的用例?
解决方案
我想你的 HTML 看起来像这样:
<div class="dialog-content" ng-controller="你的控制器">...您的内容在这里
<button id="btnClose">关闭</button>//你的按钮在你的控制器之外
尝试:angular.element(domElement).scope()
像这样(使用带有委托事件的 jquery,因为您正在动态创建 DOM):
$(document).on("click","#btnClose",function(){var dialog = $(this).closest(".dialog");//调用它来破坏作用域.angular.element(dialog.find(".dialog-content")[0]).scope().$destroy();//或 angular.element(dialog[0]).scope().$destroy();取决于您附加范围的位置.//销毁对话框dialog.dialog("销毁");对话框删除();});
I have the following use case - I provide a dialog service where I put a different content depending on the context. In the service method i manually compile a dom element and use it to display dialog using jquery ui. The code is the following:
var _view = jQuery('<div id="config-dialog"><span ng-include="\'' + $scope.configView + '\'" ng-controller="' + $scope.configController + '"></span></div>');
var _compiled = $compile(_view.contents())($scope);
And then I fire a scope event that should be handled by a scope function defined in the controller
$scope.$broadcast('config-open', $scope.config);
then I open the dialog and the user performs something and closes the dialog. When the dialog gets closed i remove the "config-dialog" element from the DOM. Like this:
$(this).dialog("destroy");
jQuery('#config-dialog').remove();
However the next time the dialog gets opened and a new controller gets instantiated i see that the 'config-open' gets handled twice, when open the dialog again it gets handled 3 times. That means the scope attached to the ng-include that I dynamically create is not destroyed. I've debugged with Batarang and saw that really the child scope created by ng-include is not cleaned. AFAIK AngularJS scopes are associated to dom elements and when I remove the element, the scope should be garbage collected but this doesn't happen.My question is - is AngularJS supposed to clean up the scope in my case. What am I doing wrong and is there a more proper way to implement my use case?
解决方案
I suppose your HTML looks like this:
<div class="dialog">
<div class="dialog-content" ng-controller="yourcontroller">
...your content here
</div>
<button id="btnClose">Close</button> //your button is outside your controller
</div>
Try: angular.element(domElement).scope()
Like this (using jquery with delegated event because you're creating your DOM dynamically):
$(document).on("click","#btnClose",function(){
var dialog = $(this).closest(".dialog");
//call this to destroy the scope.
angular.element(dialog.find(".dialog-content")[0]).scope().$destroy();
//or angular.element(dialog[0]).scope().$destroy(); depending on where you attach your scope.
//Destroy dialog
dialog.dialog("destroy");
dialog.remove();
});
这篇关于AngularJS 不清理由 ng-include 创建的子作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!