2
votes

On my route I have a list of customers, and a form to add new ones. I create an empty record in the setupController hook. This record is bound to the form. My idea was: on saving the record I make a (deep) copy of it, save the copy, then reset the record to empty state via http://emberjs.com/api/data/classes/DS.Model.html#method_rollbackAttributes.

Looks like it wont work, because

If the model isNew it will be removed from the store.

How should I handle this scenario? What is the best practice?

I made a JsBin to demonstrate the problem. http://jsbin.com/weqotoxiwe/3/edit?html,js,output. Try to type something, then save it. (It should empty the record) then type again. It produce the following error in console:

Uncaught Error: Attempted to handle event didSetProperty on while in state root.deleted.saved. Called with {name: name, oldValue: sds, originalValue: undefined, value: sdsd}.

Here is the snippet:

App = Ember.Application.create();

App.Router.map(function() {
  // put your routes here
});

App.ApplicationAdapter = DS.RESTAdapter;

App.Customer = DS.Model.extend({
  name: DS.attr('string'),
  city: DS.attr('string')
});

App.IndexRoute = Ember.Route.extend({
  model: function() {
    return this.store.findAll('customer');
  },
  setupController: function(controller, model) {
    this._super(controller, model);
    var empty = this.store.createRecord('customer');
    controller.set('empty', empty);
  },
  actions: {
    save: function(record) {
      /*
      record.copy().then(function(copy){
        copy.save();
      })*/
      record.rollbackAttributes();
    }
  }

});



/*---------------Data------------------*/
var customers = {
  "customers": [{
    "id": 1,
    "name": "Terry Bogard",
    city: 'Delaware'
  }, {
    "id": 2,
    "name": "Joe Higashi",
    city: 'Tokyo'
  }, {
    "id": 3,
    "name": "Richard Meyer",
    city: 'Albuquerque'
  }, {
    "id": 4,
    "name": "Kim Kaphwan",
    city: 'Seoul'
  }, {
    "id": 5,
    "name": "Ryo Sakazaki ",
    city: 'Tokyo'
  }, {
    "id": 6,
    "name": "Takuma Sakazaki ",
    city: 'Tokyo'
  }, ]
};

$.mockjax({
  url: '/customers',
  dataType: 'json',
  responseText: customers
});
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>Ember Starter Kit</title>
  <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.1/normalize.css">
  <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">

  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
  <script src="http://builds.emberjs.com/beta/ember-template-compiler.js"></script>
  <script src="http://builds.emberjs.com/beta/ember.debug.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-mockjax/1.6.2/jquery.mockjax.min.js"></script>
  <script src="http://builds.emberjs.com/beta/ember-data.min.js"></script>

  <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">
</head>

<body>

  <script type="text/x-handlebars">
    <h2>Table example</h2>
    {{outlet}}
  </script>

  <script type="text/x-handlebars" data-template-name="index">
    {{input value=empty.name}}
    <button {{action 'save' empty}}>Save</button>

    {{#each model as |record|}}
    <div>{{record.name}}</div>
    {{/each}}
  </script>



</body>

</html>

Update

In my application I handle the all saves in one central place, in application route. Usually I use http://emberjs.jsbin.com/jipani/edit?html,js,output to send the action up to the route.

1

1 Answers

0
votes

I would save the record bound to the form (not a deep copy of it), and then create a new record and attach it to the form. No need to mess with deep copying or rolling back.

You should do this all on the Controller (coffeescript) -

newEmpty: (->
    empty = @store.createRecord('customer')
    @set('empty', empty)
).on('init')

actions:
    saveEmpty: ->
        @get('empty').save().then =>
            @newEmpty()    

Note that on('init') is needed to run newEmpty when the controller is initialized.