0

Let's define a trivial scenario where a blog has a list of Posts, each with Comments and other Objects.

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.

Comments are loaded when Post is first loaded, in the link method of the directive associated to <comments>. How can i trigger Comments 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 Comments reloading?
  2. Should I create a register function in the Post directive, where Comments and Objects 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.
andrea.ge
  • 1,937
  • 1
  • 18
  • 27
  • I'm unsure of your architecture in terms of data but I think if you were to load comments as objects embedded in posts, your comment directive could just bind to the posts comments collection and the changes would propagate to your UI automatically. Edit: This blog post explains nicely https://umur.io/angularjs-directives-using-isolated-scope-with-attributes/ – Drew R Jan 17 '15 at 14:12

1 Answers1

1

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 (e.g. 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.

Community
  • 1
  • 1
Peter Ashwell
  • 4,292
  • 2
  • 18
  • 22