AngularJS 不清理由 ng-include 创建的子作用域 [英] AngularJS not cleaning child scope created by ng-include

查看:20
本文介绍了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?

解决方案

The controller is only for the dialog content. OK and cancel buttons for the dialog are handled outside of the dialog content

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 创建的子作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆