-
Notifications
You must be signed in to change notification settings - Fork 27.4k
respect explicit return values from controller functions (fixes #11147) #11326
Changes from 4 commits
b89320a
57fe701
d0f1285
0266a1c
f6f0117
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4197,6 +4197,50 @@ describe('$compile', function() { | |
}); | ||
|
||
|
||
it('should respect controller return value', function() { | ||
module(function() { | ||
directive('logControllerProp', function(log) { | ||
return { | ||
controller: function($scope) { | ||
this.foo = 'baz'; // value should not be used. | ||
return {foo: 'bar'}; | ||
}, | ||
link: function(scope, element, attrs, controller) { | ||
log(controller.foo); | ||
} | ||
}; | ||
}); | ||
}); | ||
inject(function(log, $compile, $rootScope) { | ||
element = $compile('<log-controller-prop></log-controller-prop>')($rootScope); | ||
expect(log).toEqual('bar'); | ||
expect(element.data('$logControllerPropController').foo).toEqual('bar'); | ||
}); | ||
}); | ||
|
||
|
||
it('primitive controller return values are ignored', function() { | ||
module(function() { | ||
directive('logControllerProp', function(log) { | ||
return { | ||
controller: function($scope) { | ||
this.foo = 'baz'; // value *will* be used. | ||
return 'bar'; | ||
}, | ||
link: function(scope, element, attrs, controller) { | ||
log(controller.foo); | ||
} | ||
}; | ||
}); | ||
}); | ||
inject(function(log, $compile, $rootScope) { | ||
element = $compile('<log-controller-prop></log-controller-prop>')($rootScope); | ||
expect(log).toEqual('baz'); | ||
expect(element.data('$logControllerPropController').foo).toEqual('baz'); | ||
}); | ||
}); | ||
|
||
|
||
it('should get required parent controller', function() { | ||
module(function() { | ||
directive('nested', function(log) { | ||
|
@@ -4216,6 +4260,28 @@ describe('$compile', function() { | |
}); | ||
|
||
|
||
it('should get explicit return value of required parent controller', function() { | ||
module(function() { | ||
directive('nested', function(log) { | ||
return { | ||
require: '^^?nested', | ||
controller: function() { | ||
return {foo: 'bar'}; | ||
}, | ||
link: function(scope, element, attrs, controller) { | ||
log(!!controller && controller.foo); | ||
} | ||
}; | ||
}); | ||
}); | ||
inject(function(log, $compile, $rootScope) { | ||
element = $compile('<div nested><div nested></div></div>')($rootScope); | ||
|
||
expect(log).toEqual('bar; false'); | ||
}); | ||
}); | ||
|
||
|
||
it('should get required parent controller when the question mark precedes the ^^', function() { | ||
module(function() { | ||
directive('nested', function(log) { | ||
|
@@ -4524,6 +4590,30 @@ describe('$compile', function() { | |
}); | ||
|
||
|
||
it('should respect explicit controller return value when using controllerAs', function() { | ||
module(function() { | ||
directive('main', function() { | ||
return { | ||
templateUrl: 'main.html', | ||
transclude: true, | ||
scope: {}, | ||
controller: function() { | ||
this.name = 'lucas'; | ||
return {name: 'george'}; | ||
}, | ||
controllerAs: 'mainCtrl' | ||
}; | ||
}); | ||
}); | ||
inject(function($templateCache, $compile, $rootScope) { | ||
$templateCache.put('main.html', '<span>template:{{mainCtrl.name}} <div ng-transclude></div></span>'); | ||
element = $compile('<div main>transclude:{{mainCtrl.name}}</div>')($rootScope); | ||
$rootScope.$apply(); | ||
expect(element.text()).toBe('template:george transclude:'); | ||
}); | ||
}); | ||
|
||
|
||
it('should support controller alias', function() { | ||
module(function($controllerProvider) { | ||
$controllerProvider.register('MainCtrl', function() { | ||
|
@@ -5525,6 +5615,41 @@ describe('$compile', function() { | |
}); | ||
}); | ||
|
||
it('should copy the explicit return value to all clones', function() { | ||
module(function() { | ||
directive('makeThree', valueFn({ | ||
transclude: 'content', | ||
controller: function($transclude) { | ||
this.foo = 'baz'; | ||
return {transclude:$transclude, foo: 'bar'}; | ||
}, | ||
link: function(scope, el, attr, ctrl) { | ||
ctrl.transclude(cloneAttach); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't need to actually run the transclude fn, we just need to assert that it's there There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be good to make these test cases a little closer, so that the only difference between them is the presence of the transclude property of the DDO. almost there =) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so proving each clone gets the correct object reference to the parent controller has no value? (serious question) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no, this is tested elsewhere --- we only really care that the nested directive gets the right controller There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in my mind I need to call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. well to link the nested directive yes, but you don't need to call it 3 times --- an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. understood. |
||
ctrl.transclude(cloneAttach); | ||
ctrl.transclude(cloneAttach); | ||
|
||
function cloneAttach(clone) { | ||
el.append(clone); | ||
} | ||
} | ||
})); | ||
|
||
directive('nested', function(log) { | ||
return { | ||
require: '^^makeThree', | ||
link: function(scope, element, attrs, controller) { | ||
log(controller.foo); | ||
} | ||
}; | ||
}); | ||
}); | ||
inject(function(log, $compile) { | ||
element = $compile('<div make-three><div nested></div></div>')($rootScope); | ||
$rootScope.$apply(); | ||
expect(log).toEqual('bar; bar; bar'); | ||
}); | ||
}); | ||
|
||
it('should provide the $transclude controller local as 5th argument to the pre and post-link function', function() { | ||
var ctrlTransclude, preLinkTransclude, postLinkTransclude; | ||
module(function() { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are a few different circumstances that this happens, so we might need to be a bit more careful about this --- be sure to include test coverage that covers controllers for transclude directives too