.parents() in Angular?

18,822

Solution 1

EDIT: Although this answer was accepted, it's not correct. See comment and better answers below.

It does look like jQLite supports this already so if you're using angular you should be able to do this without pulling in JQuery itself.

From the docs here:

Supported instance methods: (links to jQuery Docs) A subset of the operations which jQuery supports are currently implemented. All of them are implemented using the chained operation syntax of jQuery. e.g:

$("div.foo").each(function() {
  $(this).removeClass("foo").addClass("bar");

});

$("div.bar, div.baz").css({ "border": "1px solid red"    }).children().addClass("child");



.parent([selector)]
.parents([selector)] 

Solution 2

Angular's jqLite supports parent() method, so you could get all the parents in a loop like this:

var p = element.parent();
var allParents = [];
while (p.length > 0) {
    allParents.push(p[0]);
    p = p.parent();
}

Solution 3

I'm not certain you'd want to be using DOM parent references when trying to interface with Angular controllers. But not knowing what your goal is, the standard methods .parentNode, is what you're looking for. Then you'd have to loop until you hit body, or html, or null. So if you want native javascript:

var currentParent = nodeToFindParentsOf.parentNode();
var parents = [];
while(currentParent){
  parents.push(currentParent);
  currentParent = currentParent.parentNode();
}

I'm also paranoid of while loops. So would tend to wrap that whole thing in a function and put a safety valve on it to let me know what's going on, in case of crazyness in my code or in the DOM, so I'd get a clean error, instead of locking up the browser.

function getAllParentsOfNode (nodeToFindParentsOf) {
    var currentParent = nodeToFindParentsOf.parentNode();
    var parents = [];
    var safetyCount = 1000;
    while(currentParent){
      parents.push(currentParent);
      currentParent = currentParent.parentNode();
      if (--safetyCount  === 0) {
        throw new Error("Something went wrong. Found 1000+ parents!")
      }
    }

    return parents;
}

Solution 4

Angularjs includes jqLite which contains some of the jQuery functions. details here: https://docs.angularjs.org/api/ng/function/angular.element

As noted in the site, it includes

parent() - Does not support selectors

The function provided is similar to the jQuery parent() function but will not take selectors, so you wont be able to filter using selector. From the jQuery documentation:

This method is similar to .parents(), except .parent() only travels a single level up the DOM tree

So short answer: no it doesnt. But it does provide a small subset of it.

Share:
18,822

Related videos on Youtube

alexandernst
Author by

alexandernst

Updated on September 16, 2022

Comments

  • alexandernst
    alexandernst over 1 year

    Is there a way I could emulate jQuery's .parents() method in Angular, without having to actually include jQuery?

    The final goal is to get all the parents of a DOM element.

    EDIT: Why I need this?

    I'm creating a directive (a dropdown-like widget). The dropdown should listen the entire <body> for clicks and close itself (if it's open) if a click is made outside of the widget's area.

    Now, I know how to create a simple directive that would listen for mouse events, like this one:

    app.directive('mouseTrap', function() {
      return function(scope, elem) {
        elem.bind('click', function(event) {
          scope.$broadcast('click', { event: event } );
        });
      };
    });
    

    ...which I would then use like this: <body mouse-trap .... > and

    $scope.$on('click', function(msg, obj) {
      console.log("click!");
    });
    

    That is where I need to check if any of the parents of the clicked object is the top-level div of my widget, and if not, close the widget.

    • Grundy
      Grundy almost 9 years
      so why you think you need this? usually in angular not works woth DOM directly, anyway angular use inside jqLite
    • A. Wolff
      A. Wolff almost 9 years
      @Grundy But does jqLite support .parents() method? I don't see it in DOC
  • webicy
    webicy about 8 years
    JQLite in this case(question) is the version that comes with angular and it does not support the .parents() method. However is has a .parent() method which does not accepts parameters / selectors. So your answer here is missleading
  • Ruairi O'Brien
    Ruairi O'Brien almost 8 years
    @webicy: you're right! I'll edit my answer and try to have it deleted. Not sure how you're supposed to manage something like this. Thanks for the comment.
  • tsemer
    tsemer over 6 years
    Matter of taste, but could shorten a bit: var aParent = nodeToFindParentsOf.parentNode(); var parents = []; while(aParent){ parents.push(aParent); aParent = aParent.parentNode(); }