require: '^something' starts searching on the current node, not the parent. #8511
Description
The docs
The docs say:
^ - Locate the required controller by searching the element's parents.
Code example
Now consider this DOM (plunk):
<node ng-init='name = "First Level"'>
<node ng-init='name = "Second Level"'>
</node>
</node>
With this directive:
.directive( 'node', function() {
return {
require: '^node',
restrict: 'E',
scope: true,
controller: function( $scope ) {
this.getName = function() {
return $scope.name;
}
},
link: function( scope, element, attrs, ctrl ) {
console.log( scope.name + ' => ' + ctrl.getName() );
}
}
});
If the docs are correct, this code should throw an error, as the top level node doesn't have a parent node. But instead the console output is:
Second Level => Second Level
First Level => First Level
The Angular code
This is the Angular code (jqLite):
function jqLiteInheritedData(element, name, value) {
// if element is the document object work with the html element instead
// this makes $(document).scope() possible
if(element.nodeType == 9) {
element = element.documentElement;
}
var names = isArray(name) ? name : [name];
while (element) {
for (var i = 0, ii = names.length; i < ii; i++) {
if ((value = jqLite.data(element, names[i])) !== undefined) return value;
}
// If dealing with a document fragment node with a host element, and no parent, use the host
// element as the parent. This enables directives within a Shadow DOM or polyfilled Shadow DOM
// to lookup parent controllers.
element = element.parentNode || (element.nodeType === 11 && element.host);
}
}
And you can see that the InheritedData search starts on the current element, not on the parent.
Hopefully a bug
So either the docs are wrong, or the code is wrong.
I'm not sure why the search starts on the current element, or what will be the consequences of changing it to start on the parent. But I've already been involved with 3 directives that could benefit from '^' search starting on the parent, as often you wish to have an hierarchy of the same directive.