我有一个对话框模板,其中包含一个指令,用于触发对后端的定期调用以检查新内容。在指令的$ destroy函数中取消间隔,当我离开时它按预期工作。但是,当我关闭模态时,嵌套指令的范围不会被破坏,即使它是a)从DOM中移除而b)在未保留的范围下。我还需要什么样的设置才能强制销毁嵌套指令?
我目前的设置有点复杂,但它基本上归结为以下几点:
编辑:说明问题的工作插件:https://plnkr.co/edit/BAlzEw2wjEuYWDVPZoCd
的index.html
<!DOCTYPE html>
<html ng-app="testapp">
<head>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.1.1/angular-material.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.3/angular-animate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.3/angular-aria.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.js"></script>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
<script src="directive1.js"></script>
<script src="directive2.js"></script>
</head>
<body ng-controller="MainCtrl">
<placeholderdirective></placeholderdirective>
<br />
<a href ng-click="openDialog1 ()">Re-open dialog</a>
</body>
</html>
dialog1.html
<md-dialog id="dialog1" aria-label="dialog">
<md-toolbar layout="row" class="dialog-header">
<div flex="grow" class="dialog-title">
<h4>
Dialog 1
</h4>
</div>
<a flex="nogrow" href ng-click="$root.hideDialog ()" class="close-dialog">×</a>
</md-toolbar>
<md-dialog-content>
<my-directive></my-directive>
</md-dialog-content>
</md-dialog>
的script.js
var app = angular.module('testapp', ['ngAnimate', 'ngAria', 'ngMaterial']);
app.value('DIALOGS',
{
'DEFAULTS':
{
autoWrap: false,
clickOutsideToClose: true,
disableParentScroll: true,
escapeToClose: true,
focusOnOpen: true,
fullscreen: false,
hasBackdrop: true,
parent: $('body'),
preserveScope: true
},
'DIALOG1':
{
templateUrl: 'dialog1.html'
}
});
app.controller ('MainCtrl', function ($mdDialog, $rootScope, $scope, DIALOGS)
{
$scope.test = 'Test';
$scope.openDialog1 = function ()
{
var params = _.assign (DIALOGS.DEFAULTS, DIALOGS.DIALOG1);
$mdDialog.show (params);
};
$rootScope.hideDialog = function ()
{
$mdDialog.hide ();
}
});
directive1.js
//-- PLACEHOLDER DIRECTIVE --
angular
.module('testapp')
.directive('placeholderdirective', ['$mdDialog', '$rootScope', 'DIALOGS',
function($mdDialog, $rootScope, DIALOGS) {
return {
restrict: 'E',
scope: {
},
template: '<div></div>',
link: function($scope, element, attributes, controller) {
function init() {
//All modals use the default values unless overridden in
//their own Object. This simply mixes the two into a single
//object, prioritizing the second argument
var params = _.assign(DIALOGS.DEFAULTS, DIALOGS.DIALOG1);
//Create an isolate scope for the dialog. This gets properly
//destroyed when the dialog closes
var child = $rootScope.$new(true);
params.scope = child;
//Display the modal
$mdDialog.show(params);
}
init();
/**
* Called when the directive is destroyed
**/
$scope.$on('$destroy', function(event) {
alert('Destroying the placeholder');
});
}
};
}
]);
directive2.js
//-- NESTED DIRECTIVE --
angular
.module('testapp')
.directive('myDirective', ['$rootScope',
function($rootScope) {
return {
restrict: 'E',
scope: {
//Note that this scope is also isolated
},
template: '<div>Hello, world!</div>',
link: function($scope, element, attributes, controller) {
/**
* Called when the directive is destroyed
**/
$scope.$on('$destroy', function(event) {
//Doesn't get called until the primary scope is destroyed,
//but I would like it to fire when the dialog closes
alert('Destroying my directive!');
});
}
};
}
]);