How to force controller destruction?


#1

Hi,

I have a use case where I have a dozen pages, where each one make 2 or 3 Ajax calls to retrieve data for rendering on a chart. I also have, on each page of the application, a date selector at the top (that stays persistent across all pages). I want to automatically reload the data of the given page whenever I change the date.

For this, my controllers do not do directly the Ajax call but rather rely on a service that do the API call, and each controller have a “reload” method that observes the date:

export default Ember.Controller.extend({
  needs: 'parent',
  date: Ember.computed.alias('controllers.parent.date'),
  
  reload: function() {
    this.get('service:my-service').getFooData(this.get('date'));
  }.observes('date')
});

Now, the problem is that if I open the 12 or 13 different pages that do this (each one have its own controller because I fetch different data), and then change the date, this will trigger the observer of ALL controllers that have already been opened, because controllers are not destroyed once they are created. Obviously, this is bad as it can potentially triggers 30-40 Ajax calls at the same time, while most of them are not being relevant for the page being shown.

How should I architecture the code for such use case?

Thanks


#2

If I have understood your question correctly there is only one of these chart pages on screen at any given time so you only want to refresh that one. This sounds like a variation of a “master-detail” view (where your “master” view contains the date picker and the “detail” view contains the chart. As you have noted, controllers are not a good fit for this but Ember’s route objects are a great fit for this problem.

I would try:

  • Move the reload functionality into the model hook of a Route object.
  • Have the datepicker trigger a transition to that route (perhaps passing in the date as a dynamic segment)

I hope that makes sense (and that I have interpreted your situation correctly). You can find more resources if you google for master-detail in Ember.

HTH

/Eoin/


#3

I think @eoinkelly approach is the right one, let the main route in charge of loading new data instead of the controllers. One think I would try (not sure it would works correctly) it is to have the date set up as query parameter for the root route, say /myapp/charts and then visualize one chart per sub-route something along the lines of: /myapp/charts/histogram /myapp/charts/lines etc.

Query parameter for /myapp/charts route should automatically append for the child routes and you should obtain one reload-point for the data and multiple view-point for the charts…


#4

Thank you. That makes a lot of sense. The reason I didn’t do this is because I had my top controller that kept references to the current date, but it’s easy to circumvent with controllerFor.

I will try that and let you know :).

Thanks a lot for the feedback