chopper
chopper

Reputation: 6709

itemController for hasMany

I've been struggling with the following question for a while: How do I assign an itemController to child elements in a hasMany relationship?

My use case is the following: I have an Ember.View (ProjectView) in which I manipulate areas on the map using the Google Maps API. I have a model for the Area and the Project model "hasMany" areas.

I do not have any save buttons or the like in my app, but rather sync changes to the backend when a change occurs (using a debounce function). In order to avoid nasty inFlight errors, I am using a modified version of the Ember.AutoSaving plugin https://github.com/gaslight/ember-autosaving, which buffers my changes and synchronizes them with the model when it's ready. However, in order to use this, I need to apply an itemController using this Mixin to every Area in my hasMany relation. How do I go about this?

Upvotes: 0

Views: 476

Answers (1)

Mike Grassotti
Mike Grassotti

Reputation: 19050

The Handlebars {{each}} helper has an itemController option. When this option is specified each object will be wrapped by a controller instance. So something like this should work:

//from your project template
{{#each area in areas itemController="area"}}
  <pre>
    area is an AreaController: {{area}}
    area.content is a reference to the model: {{area.content}}
{{/each}}

See the [handlebars {{each}} API docs] (http://emberjs.com/api/classes/Ember.Handlebars.helpers.html#method_each) for more details

EDIT: Option 2

As an alternative to using the {{each}} helper, use an ArrayController to represent the collection and set it's itemController property. For example:

App.AreasController = Ember.ArrayController.extend({
  itemController: 'area'
});

App.AreaController = Ember.ObjectController.extend( Ember.AutoSaving, {
  bufferedFields: ['title', 'body'],
  instaSaveFields: ['postedAt', 'category'],
  titleLength: function() {
    return this.get('title').length;
  }.property('title')
});

// In your project route:
setupController: function(controller, model) {
  this.controllerFor('areas').set('content', model.areas);
}

Now the areas controller will wrap each item in an AreaController proxy.

See Ember ArrayController API docs

Upvotes: 3

Related Questions