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

Commit bb9c70f

Browse files
committed
refactor($compile): throw when linking the same element more then once
1 parent cfc8b41 commit bb9c70f

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
@ngdoc error
2+
@name $compile:multilink
3+
@fullName Linking Element Multiple Times
4+
@description
5+
6+
This error occurs when a single element is linked more then once.
7+
8+
For example, if an element is compiled and linked twice without cloning:
9+
```
10+
var linker = $compile(template);
11+
linker($scope); //=> ok
12+
linker($scope); //=> multilink error
13+
```
14+
15+
Linking an element as a clone multiple times is ok:
16+
```
17+
var linker = $compile(template);
18+
linker($scope, function() { ... }); //=> ok
19+
linker($scope, function() { ... }); //=> ok
20+
```
21+
22+
However once an element has been linked it can not be re-linked as a clone:
23+
```
24+
var linker = $compile(template);
25+
linker($scope); //=> ok
26+
linker($scope, function() { ... }); //=> multilink error
27+
```

src/ng/compile.js

+7
Original file line numberDiff line numberDiff line change
@@ -1652,6 +1652,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16521652
compile.$$addScopeClass($compileNodes);
16531653
var namespace = null;
16541654
return function publicLinkFn(scope, cloneConnectFn, options) {
1655+
if (!$compileNodes) {
1656+
throw $compileMinErr('multilink', 'This element has already been linked.');
1657+
}
16551658
assertArg(scope, 'scope');
16561659

16571660
if (previousCompileContext && previousCompileContext.needsNewScope) {
@@ -1706,6 +1709,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
17061709

17071710
if (cloneConnectFn) cloneConnectFn($linkNode, scope);
17081711
if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn);
1712+
1713+
if (!cloneConnectFn) {
1714+
$compileNodes = compositeLinkFn = null;
1715+
}
17091716
return $linkNode;
17101717
};
17111718
}

test/ng/compileSpec.js

+27-2
Original file line numberDiff line numberDiff line change
@@ -3416,6 +3416,14 @@ describe('$compile', function() {
34163416
expect(element.text()).toBe('3');
34173417
});
34183418
});
3419+
3420+
it('should throw multilink error when linking the same element more then once', function() {
3421+
var linker = $compile('<div>');
3422+
linker($rootScope).remove();
3423+
expect(function() {
3424+
linker($rootScope);
3425+
}).toThrowMinErr('$compile', 'multilink', 'This element has already been linked.');
3426+
});
34193427
});
34203428

34213429

@@ -7654,6 +7662,22 @@ describe('$compile', function() {
76547662
});
76557663
});
76567664

7665+
it('should throw if a transcluded node is transcluded again', function() {
7666+
module(function() {
7667+
directive('trans', valueFn({
7668+
transclude: true,
7669+
link: function(scope, element, attr, ctrl, $transclude) {
7670+
$transclude();
7671+
$transclude();
7672+
}
7673+
}));
7674+
});
7675+
inject(function($rootScope, $compile) {
7676+
expect(function() {
7677+
$compile('<trans></trans>')($rootScope);
7678+
}).toThrowMinErr('$compile', 'multilink', 'This element has already been linked.');
7679+
});
7680+
});
76577681

76587682
it('should not leak if two "element" transclusions are on the same element (with debug info)', function() {
76597683
if (jQuery) {
@@ -7796,7 +7820,7 @@ describe('$compile', function() {
77967820
'</div>' +
77977821
'</div>' +
77987822
'</div>');
7799-
element = template($rootScope);
7823+
element = template($rootScope, noop);
78007824
$rootScope.$digest();
78017825
$timeout.flush();
78027826
$httpBackend.flush();
@@ -7806,10 +7830,11 @@ describe('$compile', function() {
78067830
$templateCache.removeAll();
78077831
var destroyedScope = $rootScope.$new();
78087832
destroyedScope.$destroy();
7809-
var clone = template(destroyedScope);
7833+
var clone = template(destroyedScope, noop);
78107834
$rootScope.$digest();
78117835
$timeout.flush();
78127836
expect(linkFn).not.toHaveBeenCalled();
7837+
clone.remove();
78137838
});
78147839
});
78157840

0 commit comments

Comments
 (0)