It will only call controllers that are children, but you are correct that you do risk calling methods unintentionally if you are not careful. In my use case, I was simply able to use a naming convention and that was good enough. As far as the third point is concerned, RegisterHook may not be the best name for what I am doing, since it is what actually calls all the hook methods. You could cache the results if they did not change, but in my case this performed sufficiently well and was not a concern.

Based on your example, however, it sounds like you will need a service with a more robust API to interact with. It sounds like you want a parent controller to mediate between arbitrary child controllers, which I think you could do in a fashion similar to mine, but with additional restrictions. I guess it really depends on what you are trying to do; if, like in your example, you want them to interact in an ordered manner, it might make sense to traverse the controller structure, but if not that is probably overkill. If you know exactly which controllers are going to be communicating with each other, you can probably do something like the following: https://gist.github.com/sonnym/9106358

Be warned, I just threw that together in a few minutes, so there are almost certainly errors. But I think I would take an approach along those lines, and it should be fairly testable with all the pieces in isolation communicating through a simple API. I hope this helps.

- Sonny

On 02/19/2014 12:39 PM, Vittorio C. wrote:
Thanks Sonny, interesting reading.
I see a few drawbacks in you approach (correct me if I'm wrong) applied to my needs:

  * As long as no interface is declared, there is a risk that I can
    call a method with same name on an unaware controller (not a
    "child controller").
  * The message is still a broadcast, this does not solve my flow problem.
    Oversimplifying:
      if (child[i].getResult() > 0 && child[i].isNotBlocking())
          child[i+1].doSomeStuff();
  * The traverse is executed every time RegisterHook is called

The solution I'm trying to implement would rather couple the directive's controllers if possible.

On Wednesday, February 19, 2014 5:14:21 PM UTC+1, Sonny Michaud wrote:

    I have done something similar and decided to create a generalized
    hooking mechanism.  In this way, you can define hook points in the
    parent controller and simply define methods on the child
    controller scope that will be automatically called at the
    appropriate point in time. You can then do whatever you want with
    the results from the child controllers, if need be, or simply
    discard them.  I also discuss the tradeoffs between this approach,
    shared state in services, and sending events back and forth.  You
    can see my write up here:
    http://sonnym.github.io/2014/02/05/hooks-in-angularjs-controllers/
    <http://sonnym.github.io/2014/02/05/hooks-in-angularjs-controllers/>

    - Sonny

    On 02/19/2014 11:09 AM, [email protected] <javascript:> wrote:
    I'm creating a directive that needs to interact with children
    directives generated through a template.

     <div my-parent="config" />

    config is an object that defines:

      * the parent model
      * his controller (eg. AnnoyngParent_Ctrl) that extends
        BaseParent_Ctrl (and optionally a set of decorators)
      * a template e.g.
        <h1>parent.title</h1>
        <ng-repeat="child in parent.children" my-child="child" />
      * a list of children. Each child has a controller (eg.
        LazyChild_Ctrl), a model and a template

    In both directives link functions I do add the controller and I
    compile the template.

    It's quite easy to have children communicate with their parent
    (scope inheritance and $emit in the child controller, require
    "^myParent" + controller in the link phase of the directive).
    Having the parent interact with their children is not as easy.
    $broadcast is an option for generic commands, not for more
    complex flows where at some point the parent needs to interact
    with a single child and do some conditional operation.
    The second option we evaluated was using a shared service (or a
    combination of service and broadcast) but this makes the flow
    control cumbersome.

    The last one we come through is to have the children "register"
    to the parent controller ( $scope.registerAsChild(this); ). While
    this seams a bad approach I've seen that something similar is
    used in the ngSwitch-ngSwitchWhen directives.
    Is there any flaw in this approach?
    Any alternative solution?


    On Thursday, May 24, 2012 5:39:07 AM UTC+2, Vojta Jína wrote:

        You can't access child scopes from parents.
        There are reasons for that (eg. easier memory management - we
        can
        easily throw away a child scope, without leaking memory).

        Just do what Peter suggested. Define the property on parent
        scope and
        access it from child scopes. Scopes inherit prototypically.
        See this: http://jsfiddle.net/yjVD9/1/

        V.


        On Tue, May 15, 2012 at 12:20 PM, Alexander Wilms
        <[email protected]> wrote:
        > All, I am working on a dashboard that includes several
        "modules" with
        > different contents, e.g. users tasklist, users calendar
        etc. The dashboard
        > itself has a navigation menu and some additional features.
        Each module is
        > implemented as it's own controller and template, so they
        can be re-used in
        > other pages of the same application. So the app structure
        is like:
        > <MainController with navigation menu and app header>
        >  <TasklistController/> <CalendarController/>
        <OtherControllers/>
        > </MainController>
        > Now I'd like to some data from the "child modules" to be
        displayed in the
        > parent controller, e.g. show the number of tasks in the app
        header. While I
        > found some posts describing how to inherit data from the
        parent to the child
        > controllers I'd like to have it the other way round. How
        can that be
        > achieved?  (I am both a newbie to Angular and a designer,
        not a developers,
        > so please keep it simple :-)
        > Thanks so much,
        > Alex
        >
        > --
        > You received this message because you are subscribed to the
        Google Groups
        > "AngularJS" group.
        > To view this discussion on the web visit
        > https://groups.google.com/d/msg/angular/-/PpWzqLkzp98J
        <https://groups.google.com/d/msg/angular/-/PpWzqLkzp98J>.
        > To post to this group, send email to [email protected].
        > To unsubscribe from this group, send email to
        > [email protected].
        > For more options, visit this group at
        > http://groups.google.com/group/angular?hl=en
        <http://groups.google.com/group/angular?hl=en>.

-- You received this message because you are subscribed to the
    Google Groups "AngularJS" group.
    To unsubscribe from this group and stop receiving emails from it,
    send an email to [email protected] <javascript:>.
    To post to this group, send email to [email protected]
    <javascript:>.
    Visit this group at http://groups.google.com/group/angular
    <http://groups.google.com/group/angular>.
    For more options, visit https://groups.google.com/groups/opt_out
    <https://groups.google.com/groups/opt_out>.

--
You received this message because you are subscribed to the Google Groups "AngularJS" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.

--
You received this message because you are subscribed to the Google Groups 
"AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to