fix(ngMessages): create new scope for ngMessage, clean it up correctly
Previously, ngMessage elements used the same scope as ngMessages. When ngMessage has interpolation in the textContent, then removing the message would not remove the watcher from the scope - it would only be removed when the whole ngMessages element was removed. This commit changes the ngMessage transclude function to create a new child scope instead, which can be destroyed safely when the message element is removed and the message is detached Fixes #14307 PR (#14308)
This commit is contained in:
@@ -684,7 +684,7 @@ function ngMessageDirectiveFactory() {
|
||||
},
|
||||
attach: function() {
|
||||
if (!currentElement) {
|
||||
$transclude(scope, function(elm) {
|
||||
$transclude(function(elm, newScope) {
|
||||
$animate.enter(elm, null, element);
|
||||
currentElement = elm;
|
||||
|
||||
@@ -700,6 +700,7 @@ function ngMessageDirectiveFactory() {
|
||||
ngMessagesCtrl.deregister(commentNode);
|
||||
messageCtrl.detach();
|
||||
}
|
||||
newScope.$destroy();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -609,6 +609,34 @@ describe('ngMessages', function() {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should clean-up the ngMessage scope when a message is removed',
|
||||
inject(function($compile, $rootScope) {
|
||||
|
||||
var html =
|
||||
'<div ng-messages="items">' +
|
||||
'<div ng-message="a">{{forA}}</div>' +
|
||||
'</div>';
|
||||
|
||||
element = $compile(html)($rootScope);
|
||||
$rootScope.$apply(function() {
|
||||
$rootScope.forA = 'A';
|
||||
$rootScope.items = {a: true};
|
||||
});
|
||||
|
||||
expect(element.text()).toBe('A');
|
||||
var watchers = $rootScope.$countWatchers();
|
||||
|
||||
$rootScope.$apply('items.a = false');
|
||||
|
||||
expect(element.text()).toBe('');
|
||||
// We don't know exactly how many watchers are on the scope, only that there should be
|
||||
// one less now
|
||||
expect($rootScope.$countWatchers()).toBe(watchers - 1);
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
describe('when including templates', function() {
|
||||
they('should work with a dynamic collection model which is managed by ngRepeat',
|
||||
{'<div ng-messages-include="...">': '<div ng-messages="item">' +
|
||||
|
||||
Reference in New Issue
Block a user