Koala7
Koala7

Reputation: 1404

Add and push additional objects on the fly with Ember

I am trying to add and push additional objects in my application. I have reproduced the case in this jsBin

To Achieve that I have followed this tutorial, which does exactly what I want.

I have a list of invoices and any invoice is composed by transactions. I can create a new invoice in my invoices create route where I want to add and push any single transaction.

  actions: {
    add: function() {
      var newTransaction = Ember.Object.create({
        name: "New Transaction",
        quantity: null,
        selectedFare: null,
        isDone: false
      });

      return this.get("content").pushObject(newTransaction);
    }

In my template this is how it looks

<tr>
{{#each controller}}
  <td>{{name}} {{input type=checkbox value=isDone checked=isDone}} {{input valueBinding=quantity}} {{view Em.Select prompt="test" contentBinding="controllers.fare.content" optionLabelPath="content.name" optionValuePath="content.id" selectionBinding="controllers.fare.selectedFare" }}</td>
{{/each}}
</tr>

Unfortunately I can not really see the error in the console. I don't know what is going wrong.

If from the template you remove{{#each controller}}{{/each}}, you can see one single transaction.

What's wrong in my code?

Upvotes: 3

Views: 368

Answers (3)

guleria
guleria

Reputation: 751

In your invoices/edit template you are using

{{#each controller}}

but your InvoicesCreateController is ObjectController which is causing the issue. Either don't use #each in template because I am not getting why it is required or if it is really needed then change the InvoicesCreateController to ArrayController.

Upvotes: 1

user3995789
user3995789

Reputation: 3460

I made some changes, but it needs improvement, feel free to ask further questions to improve it. Also see the emberjs guides todo example. Probably the tutorial is outdated see Ember store.push with hasMany doesn't update template?.

I refactored your add method like this:

add: function() {

  var transactionRecord = this.store.createRecord('transaction', {
    name: 'new transaction'
  });

  return this.get("model.transactions").addObject(transactionRecord);
}

The template to loop transactions is like this:

{{#each model.transactions}}

Finally I added invoices/index template so you can see the invoices and their transactions, when you click an invoice:

<script type="text/x-handlebars" data-template-name="invoice/index">
  <p> Invoice Index Route</p>
  <p> {{title}} </p>
  <p> Transactions: </p>
    {{#each transactions}}
      <ul>
        <li> name: {{name}} </li>
        <li> quantity: {{quantity}} </li>
      </ul>
    {{/each}}
</script>

The example: http://jsbin.com/gugukewaka/1/edit

Upvotes: 2

Lazybensch
Lazybensch

Reputation: 506

Embers #each helper switches the current scope like so:

// this context is the controller
{{#each controller}}
 <td>{{name}}<td/> // this context is each transaction
{{/each}}

So whenever you try to access controllers you try to accesses it on your transaction object, where it doesn't exist. The reason why this worked in the tutorial you were following is that the guy there didn't try to access a controller property. No worries, this is confusing a lot of people and will therefore be deprecated in future ember versions.

To solve your problem, just use

// this context is the controller
{{#each transaction in controller}}
 <td>{{transaction.name}}<td/> // this context is still the controller
{{/each}}

or in your particular use case:

<tr>
{{#each transaction in controller}}
  <td>{{transaction.name}} {{input type=checkbox value=transaction.isDone checked=transaction.isDone}} {{input valueBinding=transaction.quantity}} {{view Em.Select prompt="test" contentBinding="controllers.fare.content" optionLabelPath="content.name" optionValuePath="content.id" selectionBinding="controllers.fare.selectedFare" }}</td>
{{/each}}
</tr>

Upvotes: 2

Related Questions