Thanks to visit codestin.com
Credit goes to github.com

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

require: '^something' starts searching on the current node, not the parent. #8511

Closed
@Izhaki

Description

@Izhaki

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions