Javascript AngularJS未清理ng include创建的子作用域

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><

我有以下用例-我提供了一个对话框服务,根据上下文放置不同的内容。在服务方法中,我手动编译一个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);
然后我打开对话框,用户执行一些操作并关闭对话框。当对话框关闭时,我从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>