What is the best way to modify state on existing controller?


#1

I’m finding over and over again that I often need to modify a controller and using a route to do so helps because I get back button support. But I’m starting to ask the “why do I need a route” just to filter or sort or page an existing controller?

In the simple example below I paginate a list of people (nothing special here). But what I dislike about it is that because I have a route, I need to create a model. The only model that made sense was a simple “page” model as the route was specific to the page you wanted to view.

If creating this “pseudo” model wasn’t bad enough, the entire “responsibility” of the PageRoute is to modify state on another controller (not a good feeling here either). So my question is 2 fold -am I just “doing it wrong” or is the “ember way” to create routes like this even though they simply modify another controller (and have no real state of their own) ?

PersonApp.Router.map(function(match) {
    this.resource("person", { path: "/" }, function() {
        this.route("page", { path: "/page/:page_id" });
    });
});

PersonApp.PersonPageRoute = Ember.Route.extend({
    model: function(params) {
        return Ember.Object.create({id: params.page_id});
    },
    setupController: function(controller, model) {
        this.controllerFor('person').set('selectedPage', model.get('id'));
    }
});

PersonApp.PersonRoute = Ember.Route.extend({
    model: function(params) {
        this.controllerFor('person').set('selectedPage', 1);
        return PersonApp.Person.find();
    }
});

PersonApp.Person = DS.Model.extend({
    username: DS.attr('string')
});

Thank you in advance


#2

Could you factor the “things that need to be paged” so that you can cram them each into a generic model object that has the properties necessary for paging? Would that even help?


#3

It still feels strange that I need to create a model for something like this. Assume I only need to page a controller -why would I need to create a model for this? It only modifies state on an existing controller? I just wanted to spur up a discussion about what alternatives to the routing stuff exist / or should be added before a solid 1.0 release of the framework


#4

You could have an action trigger an event that bubbles up to the events hash on the application route. From there just do what you need to do on the whatever controller, no need to have a model that doesn’t do anything.


#5

@toranb I have created a model for my PageRoute and change my pageable controllers state as you did. But for more common, I created a more generic PageRoute as follows:

Ember.Route.reopen({
  getParentRoute: function() {
    var handlerInfos = this.router.router.currentHandlerInfos;

    var parent, current, self = this;
    handlerInfos.forEach(function(h) {
      current = h.handler;
      if (current == this)  return false;
      parent = current;
    return parent;
  }
});

App.PageRoute = Ember.Route.extend({
  model: function(params) {
    return Ember.Object.create({ id: params.page_id });
  },

  setupController: function(controller, model) {
    this.getCurrentController().set('currentPage', model.get('id'));
  },

  renderTemplate: function() {
    var parentRouteName = this.getParentRoute().get('routeName');
    this.render(parentRouteName + '/index', controller: this.getCurrentController());
  },

  getCurrentController: function() {
    this.controllerFor(this.getParentRoute().get('routeName').camelize());
  }
});