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

Commit 6bad48b

Browse files
committed
test($compile): test $destroy event and data removal on replaced nodes
1 parent 32d3cbb commit 6bad48b

File tree

1 file changed

+125
-1
lines changed

1 file changed

+125
-1
lines changed

test/ng/compileSpec.js

+125-1
Original file line numberDiff line numberDiff line change
@@ -5676,7 +5676,9 @@ describe('$compile', function() {
56765676

56775677
testCleanup();
56785678

5679-
expect(cleanedCount).toBe(xs.length);
5679+
// The ng-repeat template is removed/cleaned (the +1)
5680+
// and each clone of the ng-repeat template is also removed (xs.length)
5681+
expect(cleanedCount).toBe(xs.length + 1);
56805682

56815683
// Restore the previous jQuery.cleanData.
56825684
jQuery.cleanData = currentCleanData;
@@ -7872,4 +7874,126 @@ describe('$compile', function() {
78727874
expect(element.hasClass('fire')).toBe(true);
78737875
}));
78747876
});
7877+
7878+
describe('element replacement', function() {
7879+
it('should broadcast $destroy only on removed elements, not replaced', function() {
7880+
var linkCalls = [];
7881+
var destroyCalls = [];
7882+
7883+
module(function($compileProvider) {
7884+
$compileProvider.directive('replace', function() {
7885+
return {
7886+
multiElement: true,
7887+
replace: true,
7888+
templateUrl: 'template123'
7889+
};
7890+
});
7891+
7892+
$compileProvider.directive('foo', function() {
7893+
return {
7894+
priority: 1, // before the replace directive
7895+
link: function($scope, $element, $attrs) {
7896+
linkCalls.push($attrs.foo);
7897+
$element.on('$destroy', function() {
7898+
destroyCalls.push($attrs.foo);
7899+
});
7900+
}
7901+
};
7902+
});
7903+
});
7904+
7905+
inject(function($compile, $templateCache, $rootScope) {
7906+
$templateCache.put('template123', '<p></p>');
7907+
7908+
$compile(
7909+
'<div replace-start foo="1"><span foo="1.1"></span></div>' +
7910+
'<div foo="2"><span foo="2.1"></span></div>' +
7911+
'<div replace-end foo="3"><span foo="3.1"></span></div>'
7912+
)($rootScope);
7913+
7914+
expect(linkCalls).toEqual(['2', '3']);
7915+
expect(destroyCalls).toEqual([]);
7916+
$rootScope.$apply();
7917+
expect(linkCalls).toEqual(['2', '3', '1']);
7918+
expect(destroyCalls).toEqual(['2', '3']);
7919+
});
7920+
});
7921+
7922+
function getAll($root) {
7923+
// check for .querySelectorAll to support comment nodes
7924+
return [$root[0]].concat($root[0].querySelectorAll ? sliceArgs($root[0].querySelectorAll('*')) : []);
7925+
}
7926+
7927+
function testCompileLinkDataCleanup(template) {
7928+
inject(function($compile, $rootScope) {
7929+
var toCompile = jqLite(template);
7930+
7931+
var preCompiledChildren = getAll(toCompile);
7932+
forEach(preCompiledChildren, function(element, i) {
7933+
jqLite.data(element, 'foo', 'template#' + i);
7934+
});
7935+
7936+
var linkedElements = $compile(toCompile)($rootScope);
7937+
$rootScope.$apply();
7938+
linkedElements.remove();
7939+
7940+
forEach(preCompiledChildren, function(element, i) {
7941+
expect(jqLite.hasData(element)).toBe(false, "template#" + i);
7942+
});
7943+
forEach(getAll(linkedElements), function(element, i) {
7944+
expect(jqLite.hasData(element)).toBe(false, "linked#" + i);
7945+
});
7946+
});
7947+
}
7948+
it('should clean data of element-transcluded link-cloned elements', function() {
7949+
testCompileLinkDataCleanup('<div><div ng-repeat-start="i in [1,2]"><span></span></div><div ng-repeat-end></div></div>');
7950+
});
7951+
it('should clean data of element-transcluded elements', function() {
7952+
testCompileLinkDataCleanup('<div ng-if-start="false"><span><span/></div><span></span><div ng-if-end><span></span></div>');
7953+
});
7954+
7955+
function testReplaceElementCleanup(dirOptions) {
7956+
var template = '<div></div>';
7957+
module(function($compileProvider) {
7958+
$compileProvider.directive('theDir', function() {
7959+
return {
7960+
multiElement: true,
7961+
replace: dirOptions.replace,
7962+
transclude: dirOptions.transclude,
7963+
template: dirOptions.asyncTemplate ? undefined : template,
7964+
templateUrl: dirOptions.asyncTemplate ? 'the-dir-template-url' : undefined
7965+
};
7966+
});
7967+
});
7968+
inject(function($templateCache, $compile, $rootScope) {
7969+
$templateCache.put('the-dir-template-url', template);
7970+
7971+
testCompileLinkDataCleanup(
7972+
'<div>' +
7973+
'<div the-dir-start><span></span></div>' +
7974+
'<div><span></span><span></span></div>' +
7975+
'<div the-dir-end><span></span></div>' +
7976+
'</div>'
7977+
);
7978+
});
7979+
}
7980+
it('should clean data of elements removed for directive template', function() {
7981+
testReplaceElementCleanup({});
7982+
});
7983+
it('should clean data of elements removed for directive templateUrl', function() {
7984+
testReplaceElementCleanup({asyncTmeplate: true});
7985+
});
7986+
it('should clean data of elements transcluded into directive template', function() {
7987+
testReplaceElementCleanup({transclude: true});
7988+
});
7989+
it('should clean data of elements transcluded into directive templateUrl', function() {
7990+
testReplaceElementCleanup({transclude: true, asyncTmeplate: true});
7991+
});
7992+
it('should clean data of elements replaced with directive template', function() {
7993+
testReplaceElementCleanup({replace: true});
7994+
});
7995+
it('should clean data of elements replaced with directive templateUrl', function() {
7996+
testReplaceElementCleanup({replace: true, asyncTemplate: true});
7997+
});
7998+
});
78757999
});

0 commit comments

Comments
 (0)