2
votes

I am attempting to create a new record, however none of the data from the fields is being passed automatically, as I expected Ember to (from what I've read).

My template:

<form {{action save content on="submit"}}>
{{input value=name}}
<button type="submit"}}>Next</a>

From what I've read content is an alias for model and interchanging these makes no difference.

My route:

App.CampaignsNewRoute = Ember.Route.extend({
  actions: {
    save: function(campaign) {
      console.log(campaign.name);
    }
  },

  model: function(controller) {
    return this.store.createRecord('campaign');
  }
});

And my controller:

App.CampaignsNewController = Ember.ObjectController.extend({
  pageTitle: 'New Campaign Setup'
});

When I hit 'Next' it logs undefined. Logging just the campaign shows it's an Ember model, but without the name attribute. name is defined on the campaign model. Setting the input to {{input value=content.name}} places the name attribute within the model returned, but it's still undefined. Am I missing anything in this process? The EmberJS site doesn't show how to do this, from what I can find.

--

As a side note: I was originally using App.CampaignsNewController = Ember.Controller.extend as my model was returning a hash of promises, one of which is an array and Ember didn't like me using either array or object controller. I simplified it to the above to verify it wasn't that which was causing the issue. So any solution taking this into account would be wonderful.

Edit: I can access the template fields by doing this.get('controller').get('name') but surely that is not necessary? Changing my controller to a Ember.Controller.extend also stops that from working, would love to know why. Clarification on best practice here would still be wonderful!

Edit2: this.get('controller.content').get('name') works if the controller is simply an Ember.Controller as opposed to Ember.ObjectController and the template has {{input value=content.name}}. I'll work with but hopefully someone can clarify this is the correct way.

1

1 Answers

1
votes

ObjectController is the way to go here. You would have it backed by one particular model, your new model, and you would add additional properties to the controller for use in the template.

Code

App.IndexRoute = Ember.Route.extend({
  actions: {
    save: function(campaign) {
      console.log(campaign.get('color'));
    }
  },

  model: function() {
    return Ember.RSVP.hash({
      record: this.store.createRecord('color'),
      all: this.store.find('color')
    });
  },
  setupController: function(controller, model){
    this._super(controller, model.record);
    controller.set('allColors', model.all);
  }
});

App.IndexController = Em.ObjectController.extend({

});

Template

In the template any time you want to access anything on the model backing the template, you can just access it as if the model is the current scope.

{{name}}

if you want to access any of the properties that exist on the controller you would use the property name that it is on the controller.

{{allColors.length}}

Here's an example:

<form {{action save model on="submit"}}>
    Color:{{input value=color}}<br/>
   <button type="submit">Next</button>
</form>

<ul>
  {{#each item in allColors}}
    {{#unless item.isNew}}
      <li>{{item.color}}</li>
    {{/unless}}
  {{/each}}
</ul>

One last tip, always use getters and setters ;)

Ember Data hides the properties, they don't live right on the object, so campaign.name will return undefined forever and ever. If you do campaign.get('name') you'll get a real response.

With the example: http://emberjs.jsbin.com/OxIDiVU/792/edit