1

I’d appreciate if you could share you view/experience.

Suppose you have a view which contains several widgets that share some of the data (fetched from a server). For example we might have a tree, list and breadcrumbs widgets in the same view, naturally a name of a single item can be displayed in more than one widget at the same time. My question is what is the best practice of developing such views? Specifically:

  1. Are the widgets totally independent? (The easiest to implement, but suffer from performance problems)
  2. If the widgets are dependent, do they communicate through:
    1. A single model (introduces tight coupling between widgets and prevents further code evolution)
    2. Events (lose coupling but error-prone due to lose contract, less explicit code)
    3. Any other way
  3. Provided those widgets have their own controllers and scopes, how do you propagate the change notifications from the URL (or any other event) to all of them? For example if you wanna see an entity with a specific ID using URL routing, do you have a top-most view controller that is responsible to catch this change and notify all the widgets about it using some in-house mechanism, or do the widgets catch the event independently?

I guess all these questions are somehow related so feel free to answer them in whatever form/order you like.

Thanks.

2
  • By 'widget' you mean 'directive'? Commented Mar 18, 2013 at 14:18
  • Either directive or a smaller view. The idea is that this is developed as a separate UI component in the application. Commented Mar 18, 2013 at 14:35

1 Answer 1

3

Are the widgets totally independent?

I think that is too broad of a question for us to answer, as that really depends on what the widgets/directives are doing. Are you asking if they should be using isolate scopes? See also When writing a directive in AngularJS, how do I decide if I need no new scope, a new child scope, or a new isolated scope?

do they communicate through...

Again, too broad, sorry... it depends on what the directives do. Besides the ways you already listed, you could also communicate via

  • a service, which is probably what I'd use if I had more than two directives that needed to communicate
  • require: 'controllerNameHere'. With the require approach, you would define methods on your controllers using this instead of $scope. This method is limited to essentially one-way communication though: from the directive that has require to the directive that it is requiring. E.g., on the AngularJS home page, the pane directive requires the tabs directive. This allows the pane directive to call methods on the tabs directive's controller, but the tabs directive can not call methods on the pane directive's controller. (For more on this, see 'this' vs $scope in AngularJS controllers)

how do you propagate the change notifications

That depends on the type of scopes your directives have. If you are using scope: true for your directives, you don't have to propagate anything. They can all $watch some parent scope property (and because of the way JavaScript prototypal inheritance works, all of the directives can see the parent scope properties). If you are using scope: {...}, then you can use '=' or '@' to define local directive scope variables and use $watch to watch them.

If you are concerned about performance with $watches (since they are evaluated at least once every digest cycle), then events might be more appropriate.

Another thing to consider: do you want your directives to know about URLs or just scope properties? Using scope properties would likely make your directives more reusable.

Sign up to request clarification or add additional context in comments.

4 Comments

Hi Mark. Thanks for the answer. By independent I mean - do they all have separate business logic that, for instance, fetches relevant data for display from the server. My concern is of course two-fold - if they are independent in this respect, they are easy to write and reuse, but since other widgets might require the same data it's a waste of network. If they depend on each other, on the other hand, they become tightly coupled and difficult to maintain. I will process your other suggestions in my head and let you know if they are applicable in our case. Thanks.
Mark, hi again. The communication using service or using the require attribute sounds a bit too coupled for me, this way the widgets lose their flexibility. Therefore I tend to use the event-based communication. Regarding the last question, indeed your proposed approach of listening to some property on the parent scope seems the best, because it reduces the dependency. As a whole, you can see I prefer developing independent widgets.
There are however people in my project that prefer to maintain shared model on the common (upper) scope, so all widgets can see the same data. This approach is much simpler from the communication perspective, so there's only one place where the data is located and all the widgets have access to it, so there no need to communicate, because basically you really look at the same data. However this introduces hard coupling, which I'm afraid becomes unmanageable once the product grows bigger and more complex and you start reusing widgets in other places.
@Stas, I would personally favor a service over a common upper scope. The common upper scope approach requires a certain HTML structure (or the use of $rootScope). I don't recommend data sharing be restricted by HTML structure.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.