jviotti
jviotti

Reputation: 18909

Access element directive children

I'm implementing a navigation directive that should have a elements for each nav item:

<navigation title="My Web Page">
  <a href="#">Home</a>
  <a href="#">About</a>
</navigation>

How Can I get access to those anchors? Accessing the element's children in link() only returns the template's children, not the 'a''s that I'm looking for.

.directive('navigation', function () {
    return {
      template: template,
      restrict: 'E',
      replace: 'true',
      scope: {
        title: '@'
      },
      link: function postLink(scope, element, attrs) {
        // This only looks in the directive's template
        console.log($(element).find('a'));            
      }
    };
  });

What am I missing? I'm looking forward to attatch an array of the anchors in the directive's scope and iterate trough them within the template.

Upvotes: 0

Views: 206

Answers (2)

adamK
adamK

Reputation: 3889

In order to move the original content within the new template you need to use the transclude property. When translude is set to true the directive will delete the original content but also make it available for reinsertion within your template through the ng-translude directive. See example below.

Without transluding the orginal data the anchor tags are removed and that is why your link function cannot find them.

.directive('navigation', function () {
    return {
        template: '<div>Tansclude data here: <span ng-translude></span></div>',
        restrict: 'E',
        replace: true,
        transclude: true,
        scope: {
            title: '@'
        },
        link: function postLink(scope, element, attrs) {
            console.log($(element).find('a'));            
        }
   };
});

Upvotes: 2

NicolasMoise
NicolasMoise

Reputation: 7279

I am a bit confused where your nav-tems are coming from, but I'll give it a go

I'm assuming your nav elements are defined in a controller that is parent to the directive

function myCtrl ($scope){
    $scope.navArray=[{title: 'Link1', href: 'www.example.com'}, {...}];
}

you would them have to declare the array as an attribute in your directive

<navigation nav="navArray"></navigation>

and two-way-bind it to the scope of your directive

.directive('navigation', function () {
    return {
      template: '<div><a ng-repeat="link in nav" href="link.href">{{link.title}}</a></div>',
      restrict: 'E',
      replace: 'true',
      scope: {
        nav: '='
      },
      link: function postLink(scope, element, attrs) {

      }
    };
  });

Remember, you want to stay away from DOM manipulation in your link function. Instead, I recommend using ng-repeat in your template, and make sure the array of nav items is passed to your directive's scope.

Edit: See Fiddle http://jsfiddle.net/nicolasmoise/8YQPh/3/

Upvotes: 1

Related Questions