简体   繁体   中英

AngularJS child directive depending on parent directive reusability

Let's define a trivial scenario where a blog has a list of Post s, each with Comment s and other Object s.

In structuring the Post page, I can image defining the following elements:

<post post="post"></post>
<comments post="post"></comments>
<objects post="post"></objects>

or:

<post post="post">
    <comments></comments>
    <objects></objects>
</post>

To provide reusability, each directive associated to an element has its own isolated scope.

Considering then for example the directive associated to <comments> , I can supply it with an Add button, a Reload comments button etc. That's easy, as long as its functions are limited to its own scope.

Comment s are loaded when Post is first loaded, in the link method of the directive associated to <comments> . How can i trigger Comment s reloading when (the parent) Post changes?

  1. In the directive associated to <comments> , should I place a scope.$watch('post') to listen when the associated Post changes and trigger on change the Comment s reloading?
  2. Should I create a register function in the Post directive, where Comment s and Object s subscribe their own controllers, and are notified from a Post function when they need to be reloaded? That is, a manually implemented Observer pattern.
  3. $broadcast and $on ? Not sure how to implement them with isolated scopes.

The most appropriate thing to do here I would say is to use an event. If the scope is isolated you can broadcast from the directive controller (or another controller) as in this answer:

AngularJS : broadcast event from directive

Here's some code demonstrating what to do with isolate scopes and events, etc:

http://plnkr.co/edit/tpl:rfqcl9AHEoJZEEJxyNn2?p=preview

app.directive('post', function() {
  return {
    scope: {},
    link: function(scope, elem, attrs) {
      console.log('post');
    },
    controller: function($scope) {
      tellComments = function() {
        console.log('telling comments');
        $scope.$broadcast('heyComments');
      };
    },
    template: '<button ng-click="tellComments()">sup</button><div comments></div>'
  };
})

app.directive('comments', function() {
  return {
    scope: {},
    link: function(scope, elem, attrs) {
      console.log('comments');
    },
    controller: function($scope) {
      $scope.$on('heyComments', function() {
        console.log('sup post!');
      });
    }
  }
})

And the template:

  <body ng-controller="MainCtrl">
    <div post>
      <button ng-click="tellComments()">click me</button>
    </div>
  </body>

So clicking the button, or doing anything else (eg loading some data) that calls the function 'tellComments' then gets sent into the child directive, handled by the controller scopes - NOT the same as the directive scopes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM