Synchronizing fetched data between multiple components / directives

47 views
Skip to first unread message

André Eife

unread,
Dec 3, 2014, 10:11:12 AM12/3/14
to ang...@googlegroups.com
I'm currently considering an alternative to my current directive handling in AngularJS. At the moment my list controller fetches the data from the server via a service and passes this data to the directives on the list page via a parameter. This works so far and keeps the two way binding, so if a directive changes the data the controller and also other directives notice the change. But it leads to a slightly bigger list controller where all the directives come together. And although the directives get their data passed in as a parameter they still need the dependency to the service which handles data server communication for altering and deleting the data.

The alternative I want to test is to let the directive itself request the data they need from the service. In order to not send the same requests to the server I enable the cache. But with this approach every directive will get a new data object. So if this data object is somehow manipulated in one directive the other directives don't know of this change and will still have the original data object.

I could save the fetched data object in the service which requests the data but this will lead into problems if different components want different parts of data, so one components needs item 1 - 10 and the other item 11 to 20.

Is there a way to achive this "directives fetch the data themself" approach while keeping the data binding between components?

Or is the approach of passing the data into the directive I currently use even better then the alternative I'm thinking of?

Would be really nice if someone could share his thoughts on this or point me to some good sources for this topic.

Sander Elias

unread,
Dec 3, 2014, 12:03:44 PM12/3/14
to ang...@googlegroups.com
Hi André.

You know directives can have controllers right? (just a slight side-remark, not much to do with your issue!)

You should separate your state, from your data. the state (I need nr 1 to 10, and I need it ordered by zzyy..) needs to be in your directive.
The data, should be in a shared service. 
This allows you to do whatever you want. If you have some really crazy things in your directive, you can even create a copy of the data in memory, and write it back whenever needed.
There will be a tax involved in that (added complexity and memory requirements), but it is a good way to keep the separations in place.
If it's something you need to do often, you might even create a service that does the copying and re-integration of the data.

Regards
Sander

André Eife

unread,
Dec 3, 2014, 1:15:07 PM12/3/14
to ang...@googlegroups.com
Hi Sander,

thanks for your answer.

Yes I have lots of directives with a controller. At the moment they receive the initial data set via a parameter and manipulate it in their controller if needed. The issue I was mentioning with nr. 1 to 10 and 11 to 20 was connected to directives calling for data on the service and the service saving the data directly in its object. Lets say you have thousands of complex items then your service can't hold every item but has to fetch them on demand.

So I still don't really know if its better to provide a directive with data via a parameter or let them fetch the data itself via a service. I wanted to try the second version because my directives already have the dependency to the service. But even if I separate state and data the data needs to be synchronized between my directives.

To clarify I added a simple minified code example:

.directive('firstDirective', function (myService){
    return {
        controller: function ($scope) {
            myService.getData().then(function (data) {
                $scope.myData = data;
            });
        }
    }
})
.directive('secondDirective', function (myService){
    return {
        controller: function ($scope) {
            myService.getData().then(function (data) {
                $scope.myData = data;
            });
        }
    }
});

Lets say myService.getData() fetches data from the server or from cache if enabled. Because the $http cache does not return a reference to the same object both directives have initially the same data but the data is not synchronized if one component changes it. I can't just simply save the data object in the service because of possible different requests like mentioned. I think what I would need is something like a cache that returns for the same request an

Sander Elias

unread,
Dec 3, 2014, 1:29:45 PM12/3/14
to ang...@googlegroups.com

Hi André

Well, if your directives use separate pieces of data, the syncing isn’t a issue to begin with, and keeping the state out of the data is enough right?
Otherwise make sure the service takes care of the syncing. Keep the cache in the service, and hand out references in stead of copies.
You can do something like myService.getData({start:1, end:10}) and so on.

Regards
Sander

André Eife

unread,
Dec 3, 2014, 1:42:36 PM12/3/14
to ang...@googlegroups.com
Hi,

But using this approach my service needs to have all the data. My program has a large data set on the server backend, so fetching all data is no solution. The service also can't really save new items when they are first requested and so build its own local memory over time because of the start and end parameter. Lets say some items get deleted then its really hard to keep track of which start and end to call for or check if they are already fetched.

Some use case examples:
* directive 1 requests item 1 - 500
* directive 2 requests item 15634
* directive 3 requests all items with name=*test
* directive 4 requests item 1 - 500

So directive 1 and 4 basically use the same data and it would be good if they would synchronize, so if directive 1 changes the data then 4 notices it and vice versa. The service can't save all data and there can be a large variant of requests for items like in directive 3.

That all is no problem currently because my list controller fetches the data needed, like data for 1 and 4 and passes them to the directives. Because the same object is passed to both directives and they use two way binding the data is always synchronized. I just don't see any solution achiving this when each directive should fetch the data directly with the service.

--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/FWYpwl_H6t0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Sander Elias

unread,
Dec 3, 2014, 2:29:29 PM12/3/14
to ang...@googlegroups.com
Hi,

Well, In this case you might need to see on a per directive base what you need. For example your directive 1 and 4 use their parent controller (Which might be in yet another directive!) and your directive 2 and 3 use a service. 
You can create a service that takes care of everything you need, but that's demanding some complicated stuff to be in there. Manual caching an keeping references and stuff like that. It can be done, but it might be overkill for what you are aiming for.

Regards
Sander
 

André Eife

unread,
Dec 4, 2014, 4:47:50 AM12/4/14
to ang...@googlegroups.com
Hi,

thanks for the ideas. Yes I think such a use case can be pretty complicated to handle in one service. I was just wondering if there may be already a solution, like $http cache returning only references to the same object or something. 

The current approach I use by passing data to the directives from a parent controllers works so far and often the parent controller also is a directive. Its just that over time some "main controllers" develop with more and more directives and data to pass.
Reply all
Reply to author
Forward
0 new messages