Javascript AngularJS未清理ng include创建的子作用域
我有以下用例-我提供了一个对话框服务,根据上下文放置不同的内容。在服务方法中,我手动编译一个dom元素,并使用它使用jquery ui显示对话框。代码如下:Javascript AngularJS未清理ng include创建的子作用域,javascript,angularjs,angularjs-scope,Javascript,Angularjs,Angularjs Scope,我有以下用例-我提供了一个对话框服务,根据上下文放置不同的内容。在服务方法中,我手动编译一个dom元素,并使用它使用jquery ui显示对话框。代码如下: var _view = jQuery('<div id="config-dialog"><span ng-include="\'' + $scope.configView + '\'" ng-controller="' + $scope.configController + '"></span><
var _view = jQuery('<div id="config-dialog"><span ng-include="\'' + $scope.configView + '\'" ng-controller="' + $scope.configController + '"></span></div>');
var _compiled = $compile(_view.contents())($scope);
然后我打开对话框,用户执行一些操作并关闭对话框。当对话框关闭时,我从DOM中删除“config dialog”元素。像这样:
$(this).dialog("destroy");
jQuery('#config-dialog').remove();
但是,下次打开对话框并实例化新控制器时,我看到“config open”被处理了两次,再次打开对话框时,它被处理了3次。这意味着我动态创建的附加到ng include的范围没有被销毁。我用Batarang进行了调试,发现ng include创建的子作用域实际上没有被清理。AFAIK AngularJS作用域与dom元素相关联,当我删除该元素时,应该对作用域进行垃圾收集,但这不会发生。
我的问题是-AngularJS是否应该在我的案例中清理范围。我做错了什么?有没有更合适的方法来实现我的用例?当对话框关闭时,您应该手动销毁范围 例如,假设对话框中有一个dom元素,它有一个ng click:
<div class="dialog">
....
<a data-ng-click="closeDialog()">Close Me!</a>
....
</div>
我认为您遇到的问题是,您认为通过销毁元素,范围就被销毁了。那不是真的。您必须手动销毁范围
控制器仅用于对话框内容。确定和取消按钮
对于对话框,在对话框内容之外处理
我想您的HTML如下所示:
<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>
我将做一些我通常不做的事情,并建议你采取完全不同的方法。您的问题很可能是由于JQuery和Angular的组合而产生的(还没有尝试过您的代码,但这似乎是最有可能的原因)。Angular会丢失框架外所做工作的轨迹,这是除非你真的必须混合的原因之一 在这个特定的例子中,据我所知,在Angular中没有什么是你不能做的 如果我要这样做,我可能会首先将对话框放在一个内部(它会像JQuery一样从DOM中添加和删除内容),然后让我的打开广播和关闭按钮触发ng开关条件。然后就有了一个从DOM中添加和删除的对话框,这样就不必担心Angular和Jquery之间的同步了 阅读第二部分!我以前在Angular中到处使用Jquery,然后我读了这篇文章并停了下来。现在一切都变得更加顺利了:-)
编辑:一个小的html示例。本例中的“dialog.template”是由调用程序设置的DialogController范围内的一个变量
<div ng-switch on="dialog_status">
<div ng-switch-when="open">
<div class="dialog" ng-controller="DialogController" ng-include="dialog.template">
Dialog will appear here
</div>
</div>
</div>
对话框将出现在此处
你有小提琴/钢琴吗?我们可能缺少一些详细信息。这对我不起作用,因为控制器仅用于对话框内容。对话框的“确定”和“取消”按钮在对话框内容之外处理。是否有文档描述scopoe何时被破坏以及关于控制范围生命周期的最佳实践?是否将js小提琴放在一起?我想看看你是如何构建封闭部分的。这是正确的,但是否有一篇教程/博客文章描述了作用域以及如何正确管理它们,即使是动态内容。@AdrianMitev:我在angular js的官方网站上(不知道是否有更好的网站)了解了angular js的所有内容。你可以找到很多信息。就像您的案例一样,您可以在中找到信息,并且我的对话框必须显示具有特定控制器的不同类型的视图。您建议如何使用ng switch来实现这一点?假设您已经有了可以包含的现有模板(看起来像是从您的emaple中获得的),那么您可以用与现在几乎相同的方式使用ng include。您切换的内容可以包含一个带有ng include={{some_scope_parameter}}的div。
<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>
$(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();
});
<div ng-switch on="dialog_status">
<div ng-switch-when="open">
<div class="dialog" ng-controller="DialogController" ng-include="dialog.template">
Dialog will appear here
</div>
</div>
</div>