From 45f9f62367221b2aa097ba1d87d744e50140ddc7 Mon Sep 17 00:00:00 2001
From: Igor Minar
Date: Thu, 18 Jul 2013 11:30:32 -0700
Subject: fix($compile): always instantiate controllers in parent->child order
Previously it was possible to get into a situation where child controller
was being instantiated before parent which resulted in an error.
Closes #2738
---
test/ng/compileSpec.js | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 89 insertions(+)
(limited to 'test')
diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js
index 97a58c10..c7821878 100755
--- a/test/ng/compileSpec.js
+++ b/test/ng/compileSpec.js
@@ -2331,6 +2331,95 @@ describe('$compile', function() {
expect(asyncCtrlSpy).toHaveBeenCalledOnce();
});
});
+
+
+
+ it('should instantiate controllers in the parent->child order when transluction, templateUrl and replacement ' +
+ 'are in the mix', function() {
+ // When a child controller is in the transclusion that replaces the parent element that has a directive with
+ // a controller, we should ensure that we first instantiate the parent and only then stuff that comes from the
+ // transclusion.
+ //
+ // The transclusion moves the child controller onto the same element as parent controller so both controllers are
+ // on the same level.
+
+ module(function() {
+ directive('parentDirective', function() {
+ return {
+ transclude: true,
+ replace: true,
+ templateUrl: 'parentDirective.html',
+ controller: function (log) { log('parentController'); }
+ };
+ });
+ directive('childDirective', function() {
+ return {
+ require: '^parentDirective',
+ templateUrl: 'childDirective.html',
+ controller : function(log) { log('childController'); }
+ };
+ });
+ });
+
+ inject(function($templateCache, log, $compile, $rootScope) {
+ $templateCache.put('parentDirective.html', '
parentTemplateText;
');
+ $templateCache.put('childDirective.html', 'childTemplateText;');
+
+ element = $compile('')($rootScope);
+ $rootScope.$apply();
+ expect(log).toEqual('parentController; childController');
+ expect(element.text()).toBe('parentTemplateText;childTemplateText;childContentText;')
+ });
+ });
+
+
+ it('should instantiate controllers in the parent->child->baby order when nested transluction, templateUrl and ' +
+ 'replacement are in the mix', function() {
+ // similar to the test above, except that we have one more layer of nesting and nested transclusion
+
+ module(function() {
+ directive('parentDirective', function() {
+ return {
+ transclude: true,
+ replace: true,
+ templateUrl: 'parentDirective.html',
+ controller: function (log) { log('parentController'); }
+ };
+ });
+ directive('childDirective', function() {
+ return {
+ require: '^parentDirective',
+ transclude: true,
+ replace: true,
+ templateUrl: 'childDirective.html',
+ controller : function(log) { log('childController'); }
+ };
+ });
+ directive('babyDirective', function() {
+ return {
+ require: '^childDirective',
+ templateUrl: 'babyDirective.html',
+ controller : function(log) { log('babyController'); }
+ };
+ });
+ });
+
+ inject(function($templateCache, log, $compile, $rootScope) {
+ $templateCache.put('parentDirective.html', 'parentTemplateText;
');
+ $templateCache.put('childDirective.html', 'childTemplateText;');
+ $templateCache.put('babyDirective.html', 'babyTemplateText;');
+
+ element = $compile('' +
+ '
' +
+ 'childContentText;' +
+ '
babyContent;
' +
+ '
' +
+ '
')($rootScope);
+ $rootScope.$apply();
+ expect(log).toEqual('parentController; childController; babyController');
+ expect(element.text()).toBe('parentTemplateText;childTemplateText;childContentText;babyTemplateText;')
+ });
+ });
});
--
cgit v1.2.3