user215674
user215674

Reputation: 167

Ember Adding Has Many Child Model to be Selected from Drop Down

In Ember, I have two models, Product and Genre, with Product having many Genres, set up like this.

App.Product = DS.Model.extend({
  title: DS.attr(),

  genres: DS.hasMany('genre')
});


App.Genre = DS.Model.extend({
  name: DS.attr(),

  product: DS.belongsTo('product')
});

Genres can be created on a separate page, and then multiple genres can be set for a product on the product page by selecting from a select element, with the option to add extra genres. The controller and template are set up as below.

App.ProductController = Ember.ObjectController.extend({
  availableGenres: function() {
    return this.store.findAll('genre');
  }.property(),
  actions: {
    saveProduct: function() {
      var product = this.get('model');
      product.save();
    },
    addGenre: function() {
      var product = this.get('model');
      var genre = this.store.createRecord('genre');
      product.get('genres').pushObject(genre);
    }
  }
});

And the template:

{{#each genre in genres}}    
{{view "select" content=availableGenres value=genre.name}}
{{/each}}
<button {{action 'addGenre'}}>Add Genre</button>

In layman's terms, the addGenre function should add a new select to the UI, allowing the user to select from the predefined set of genres.

The way this is currently set up, it creates a new genre, which is incorrect. What I can't work out is how I am supposed create a new genre select in the view, without creating a new genre.

How do I create a new select for a genre without creating a new genre? Setting it to the first genre from possibleGenres would suffice, but I am stuck working out how to select the first genre within that function. I'm fairly new to Ember, so any help is much appreciated!

Upvotes: 0

Views: 122

Answers (1)

MrVinz
MrVinz

Reputation: 874

it's because your addGenre creates new Genre ... :)

 addGenre: function() {
      var product = this.get('model');
      var genre = this.store.createRecord('genre'); //here you create a new genre
      product.get('genres').pushObject(genre); //and then you push the object
    }

from the select doc your select should look like :

{{view "select"
       content=availableGenres 
       optionValuePath="content" 
       optionLabelPath="content.name"
       value=selectedGenre}}

then you simply have to modify your addGenre method

addGenre: function() {
          this.get('model.genres').pushObject(this.get('selectedGenre'));
          //and eventually persist save by making a this.get('model').save() :)
        }

EDIT after the first view select add the follow

{{#each genre in model.genres}}
   {{view "select"
           content=availableGenres 
           optionValuePath="content" 
           optionLabelPath="content.name"
           value=genre}}
{{/each}}

What it does is that each time you click call the addGenre action it will add this "genre" to your object, the each just list the genres already in your object and allows you to edit them on the fly.

Upvotes: 1

Related Questions