最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Get number of child directives in parent directive before link function is executed - Stack Overflow

programmeradmin3浏览0评论

When using one directive & multiple child directives (using require), what is a way to know how many child directives will be executed?

I could just count each time the child directive is executed (in the link function). But I want the parent directive to know how many childs there are before the last link function is executed of the child directive.

I need to know because I need some specific behaviour when the last element is passed from the child to the parent directive..

When using one directive & multiple child directives (using require), what is a way to know how many child directives will be executed?

I could just count each time the child directive is executed (in the link function). But I want the parent directive to know how many childs there are before the last link function is executed of the child directive.

I need to know because I need some specific behaviour when the last element is passed from the child to the parent directive..

Share Improve this question asked Dec 5, 2014 at 13:11 VincentVincent 6,18816 gold badges56 silver badges97 bronze badges 5
  • a dirty solution could be, passing the number of child directives as an attribute to the parent directive. But I want it to happen automatically – Vincent Commented Dec 5, 2014 at 13:15
  • When you say directives, that would also include ng-repeat, ng-show, etc... are you ok with that? – Omri Aharon Commented Dec 8, 2014 at 14:55
  • Well, maybe I understood you wrong, but it seems like you want to know in a directive, how many directives appear in the DOM elements that are nested within, correct? – Omri Aharon Commented Dec 8, 2014 at 15:08
  • aah yes, only a custom one that I made, so not ng-repeat, ng-show,.. – Vincent Commented Dec 8, 2014 at 15:12
  • Or an event when all child elements are transcluded would be very usefull, but it doesn't exist – Vincent Commented Dec 8, 2014 at 15:50
Add a ment  | 

3 Answers 3

Reset to default 3 +50

You can take advantage of the fact that linking is done in two phases. You could first register all children in "pre-link phase" and then, in "post-link phase", you'd have access to the required information.

.directive('parent', function () {
    return {
        controller: function () {
            this.childCount = {
                pre: 0,
                post: 0
            };
        },
        link: function () {}
    };
})
.directive('child', function () {
    return {
        require: '^parent',
        pile: function () {
            return {
                pre: function ($scope, $element, $attrs, parentCtrl) {
                    ++parentCtrl.childCount.pre;
                },
                post: function ($scope, $element, $attrs, parentCtrl) {
                    ++parentCtrl.childCount.post;
                    if (parentCtrl.childCount.post === parentCtrl.childCount.pre) {
                        // ... (this runs only on the last linked child)
                    }
                }
            };
        }
    };
})

This way you have access to that information during last child's linking.

Of course, if you don't need the info that soon, you could just register all child controllers in the parent controller and then run a method of the last registered child controller from the parent post-link function.

I am quite sure, it cant be done without searching DOM under parent directive. But I think its not problem to do that in so specialized directive.

So I would do it like that:

var app = angular.module("app", []);

app.directive("server", function() {
  return {    
    controller: function($element) {                 
      count = $element.find("client").length
      this.call = function() {
        console.log("Server has been called");

        count --;
        if (count == 0) {
          console.log("All of them are initialized");
        }
      };
    }
  };
});

app.directive("client", function() {
  return {
    require: "^server",
    link: function($scope, $elem, $attrs, serverCtrl) {
      serverCtrl.call();
    }
  };
});

And directives looks like that:

 <server>
    <client></client>
    <client></client>
    <client></client>
  </server>

Here you can see full working example: http://jsbin./gezewidoba/1/edit?html,js,console

The execution sequence of outer and inner directives is as below

Outer - Controller
Child - Controller
Child - Link
Outer - Link

so you can use the child directive's controller to hookup into the parent directive's controller, thru some exposed function on parent directive.

And then in the link function of the inner directive, you can have logic to find out if the element is first or last, etc etc...

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论