5

次のユース ケースがあります。コンテキストに応じて異なるコンテンツを配置するダイアログ サービスを提供します。サービス メソッドでは、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」が 2 回処理され、ダイアログを再度開くと 3 回処理されることがわかります。つまり、動的に作成した ng-include にアタッチされたスコープは破棄されません。私は Batarang でデバッグしましたが、ng-include によって作成された子スコープが実際には消去されていないことがわかりました。AFAIK AngularJSスコープはdom要素に関連付けられており、要素を削除すると、スコープはガベージコレクションされるはずですが、これは起こりません。私の質問は - 私の場合、AngularJS はスコープをクリーンアップすることになっています。私のユースケースを実装するためのより適切な方法はありますか?

4

3 に答える 3

4

ダイアログを閉じているときは、実際にスコープを手動で破棄する必要があります。

例として、ダイアログに ng-click を持つ dom 要素があるとします。

<div class="dialog">
    ....
    <a data-ng-click="closeDialog()">Close Me!</a>
    ....
</div>

次に、コントローラーで、その ng クリックを次のように配線します。

function myController($scope, ....){
    ....
    $scope.closeDialog = function(){
        $scope.$destroy();
        //not to sure about the use of the word "this" here, but you should be able to figure out what element it is somehow
        $(this).dialog("destroy");
        jQuery('#config-dialog').remove();
    }
    ....
}

あなたが遭遇していると私が思う問題は、要素を破壊することによってスコープが破壊されると考えていることです。それは真実ではない。スコープを手動で破棄する必要があります。

于 2013-10-01T16:00:53.707 に答える
4

コントローラーは、ダイアログ コンテンツ専用です。ダイアログの OK ボタンとキャンセル ボタンは、ダイアログ コンテンツの外部で処理されます。

あなたの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>

試してください:angular.element(domElement).scope() このように (DOM を動的に作成しているため、委任されたイベントで jquery を使用します):

$(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();
});
于 2013-10-05T08:20:18.393 に答える