Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 860832e

Browse files
committed
test($compile): test $destroy event and data removal on replaced nodes
1 parent ed3a33a commit 860832e

File tree

1 file changed

+125
-1
lines changed

1 file changed

+125
-1
lines changed

test/ng/compileSpec.js

Lines changed: 125 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5820,7 +5820,9 @@ describe('$compile', function() {
58205820

58215821
testCleanup();
58225822

5823-
expect(cleanedCount).toBe(xs.length);
5823+
// The ng-repeat template is removed/cleaned (the +1)
5824+
// and each clone of the ng-repeat template is also removed (xs.length)
5825+
expect(cleanedCount).toBe(xs.length + 1);
58245826

58255827
// Restore the previous jQuery.cleanData.
58265828
jQuery.cleanData = currentCleanData;
@@ -8016,4 +8018,126 @@ describe('$compile', function() {
80168018
expect(element.hasClass('fire')).toBe(true);
80178019
}));
80188020
});
8021+
8022+
describe('element replacement', function() {
8023+
it('should broadcast $destroy only on removed elements, not replaced', function() {
8024+
var linkCalls = [];
8025+
var destroyCalls = [];
8026+
8027+
module(function($compileProvider) {
8028+
$compileProvider.directive('replace', function() {
8029+
return {
8030+
multiElement: true,
8031+
replace: true,
8032+
templateUrl: 'template123'
8033+
};
8034+
});
8035+
8036+
$compileProvider.directive('foo', function() {
8037+
return {
8038+
priority: 1, // before the replace directive
8039+
link: function($scope, $element, $attrs) {
8040+
linkCalls.push($attrs.foo);
8041+
$element.on('$destroy', function() {
8042+
destroyCalls.push($attrs.foo);
8043+
});
8044+
}
8045+
};
8046+
});
8047+
});
8048+
8049+
inject(function($compile, $templateCache, $rootScope) {
8050+
$templateCache.put('template123', '<p></p>');
8051+
8052+
$compile(
8053+
'<div replace-start foo="1"><span foo="1.1"></span></div>' +
8054+
'<div foo="2"><span foo="2.1"></span></div>' +
8055+
'<div replace-end foo="3"><span foo="3.1"></span></div>'
8056+
)($rootScope);
8057+
8058+
expect(linkCalls).toEqual(['2', '3']);
8059+
expect(destroyCalls).toEqual([]);
8060+
$rootScope.$apply();
8061+
expect(linkCalls).toEqual(['2', '3', '1']);
8062+
expect(destroyCalls).toEqual(['2', '3']);
8063+
});
8064+
});
8065+
8066+
function getAll($root) {
8067+
// check for .querySelectorAll to support comment nodes
8068+
return [$root[0]].concat($root[0].querySelectorAll ? sliceArgs($root[0].querySelectorAll('*')) : []);
8069+
}
8070+
8071+
function testCompileLinkDataCleanup(template) {
8072+
inject(function($compile, $rootScope) {
8073+
var toCompile = jqLite(template);
8074+
8075+
var preCompiledChildren = getAll(toCompile);
8076+
forEach(preCompiledChildren, function(element, i) {
8077+
jqLite.data(element, 'foo', 'template#' + i);
8078+
});
8079+
8080+
var linkedElements = $compile(toCompile)($rootScope);
8081+
$rootScope.$apply();
8082+
linkedElements.remove();
8083+
8084+
forEach(preCompiledChildren, function(element, i) {
8085+
expect(jqLite.hasData(element)).toBe(false, "template#" + i);
8086+
});
8087+
forEach(getAll(linkedElements), function(element, i) {
8088+
expect(jqLite.hasData(element)).toBe(false, "linked#" + i);
8089+
});
8090+
});
8091+
}
8092+
it('should clean data of element-transcluded link-cloned elements', function() {
8093+
testCompileLinkDataCleanup('<div><div ng-repeat-start="i in [1,2]"><span></span></div><div ng-repeat-end></div></div>');
8094+
});
8095+
it('should clean data of element-transcluded elements', function() {
8096+
testCompileLinkDataCleanup('<div ng-if-start="false"><span><span/></div><span></span><div ng-if-end><span></span></div>');
8097+
});
8098+
8099+
function testReplaceElementCleanup(dirOptions) {
8100+
var template = '<div></div>';
8101+
module(function($compileProvider) {
8102+
$compileProvider.directive('theDir', function() {
8103+
return {
8104+
multiElement: true,
8105+
replace: dirOptions.replace,
8106+
transclude: dirOptions.transclude,
8107+
template: dirOptions.asyncTemplate ? undefined : template,
8108+
templateUrl: dirOptions.asyncTemplate ? 'the-dir-template-url' : undefined
8109+
};
8110+
});
8111+
});
8112+
inject(function($templateCache, $compile, $rootScope) {
8113+
$templateCache.put('the-dir-template-url', template);
8114+
8115+
testCompileLinkDataCleanup(
8116+
'<div>' +
8117+
'<div the-dir-start><span></span></div>' +
8118+
'<div><span></span><span></span></div>' +
8119+
'<div the-dir-end><span></span></div>' +
8120+
'</div>'
8121+
);
8122+
});
8123+
}
8124+
it('should clean data of elements removed for directive template', function() {
8125+
testReplaceElementCleanup({});
8126+
});
8127+
it('should clean data of elements removed for directive templateUrl', function() {
8128+
testReplaceElementCleanup({asyncTmeplate: true});
8129+
});
8130+
it('should clean data of elements transcluded into directive template', function() {
8131+
testReplaceElementCleanup({transclude: true});
8132+
});
8133+
it('should clean data of elements transcluded into directive templateUrl', function() {
8134+
testReplaceElementCleanup({transclude: true, asyncTmeplate: true});
8135+
});
8136+
it('should clean data of elements replaced with directive template', function() {
8137+
testReplaceElementCleanup({replace: true});
8138+
});
8139+
it('should clean data of elements replaced with directive templateUrl', function() {
8140+
testReplaceElementCleanup({replace: true, asyncTemplate: true});
8141+
});
8142+
});
80198143
});

0 commit comments

Comments
 (0)