Search code examples
angularjsangularjs-directivejqlite

AngularJS Directive jqLite convert .contents() to .children()


Consider this runnable example:

var app=angular.module('myapp', [])
.directive('mydct', function () {
  return {
    restrict:'EA',
    transclude:true,
    template:"<div>Template</div>",
    replace:true,
    scope:true,
    link: function (scope, elm, attrs,ctrl,transcludeFn) {
      transcludeFn( function( clone, scope ) {
        console.log(clone[0]);
        console.log(clone[1]);
        console.log(clone[2]);
        console.log(clone[3]);
        //clone[3].attr('id');
      });
    }
  };
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app='myapp'>
  <mydct>
    <div id='one'>This is one</div>
    <span id='two'>This is two</span>
  </mydct>
</body>

As you can see the clone parameter in the transcludeFunction will return the object as .contents(). This will include the text nodes. I have two questions:

  1. Is there a way of converting this contents array to a children array, thus omitting text nodes?
  2. As you can see, I will get out the text contents when accessing the elements in the array, what should I do to get them as elements, and be able to get the attribute?

Solution

  • transcludeFn( function( clone, scope ) {
        var els, i;
    
        // convert to a normal array
        els = Array.prototype.slice.call(clone);
    
        // exclude text nodes
        els = els.filter(function (element) {
            return element.nodeType !== Node.TEXT_NODE;
        });
    
        // wrap each DOMElement in a jqLite object
        for (i = 0; i < els.length; i++) {
            els[i] = angular.element(els[i]);
        }
    
        for (i = 0; i < els.length; i++) {
            // do what you like with each clone's attribute
            console.log(els[i].attr('id'));
        }
    });
    

    This is a little verbose to emphasise the steps to go through, but feel free to simplify or shorten the code where necessary.