Question

I have a fiddle (http://jsfiddle.net/kitsunde/3FKg4/) with a simple edit-save application:

<script type="text/x-handlebars">
    {{outlet}}
</script>
<script type="text/x-handlebars" id="profile/edit">
    Edit.
    <form {{action 'save' on="submit"}}>
        <div>
            <input type="email" {{bind-attr value="email"}}>
        </div>
        <button>Save</button>
    </form>
</script>
<script type="text/x-handlebars" id="profile/index">
    {{#link-to 'profile.edit'}}Edit{{/link-to}}
    {{email}}
</script>

And my application:

window.App = Ember.Application.create();

App.ApplicationAdapter = DS.FixtureAdapter.extend();

App.Router.map(function () {
    this.resource('profile', {path: '/'}, function(){
        this.route('edit');
    });
});


App.ProfileRoute = Ember.Route.extend({
  model: function() {
    return this.store.find('user').then(function(users){
      return users.get('firstObject');
    });
  }
});

App.ProfileEditRoute = App.ProfileRoute;

App.ProfileEditController = Ember.ObjectController.extend({
    actions: {
        save: function(){
            var profile = this.get('model');
            profile.setProperties({email: this.get('email')});
            profile.save();
            this.transitionTo('profile');
        }
    }
});

App.User = DS.Model.extend({
    email: DS.attr('string')
});

App.User.FIXTURES = [
    {
        id: 1,
        email: 'herpyderp@gmail.com'
    }
];

When I hit save and it goes back to profile/index it doesn't have an updated model and when I go back to profile/edit the edit isn't there. I realize I could use {{input value=email}} which does seem to remember the model changes, but that seems to persist the changes to the model as I type which isn't what I want.

What am I missing?

Was it helpful?

Solution 2

I fixed it with 2 changes. First since I was grabbing this.get('email') I was getting the models email address and not the one from input field, so it was actually never updating the data.

<script type="text/x-handlebars">
    {{outlet}}
</script>
<script type="text/x-handlebars" id="profile/edit">
    Edit.
    <form {{action 'save' on="submit"}}>
        <div>
            {{input value=email}}
        </div>
        <button>Save</button>
    </form>
    {{#link-to 'profile'}}Back{{/link-to}}
</script>
<script type="text/x-handlebars" id="profile/index">
    {{#link-to 'profile.edit'}}Edit{{/link-to}}
    {{email}}
</script>

Second to deal with only updating the model on save I used ember-data transaction handling to rollback the commit when navigating away from the current route, unless it had been saved. I also moved my logic into the router.

window.App = Ember.Application.create();

App.ApplicationAdapter = DS.FixtureAdapter.extend();

App.Router.map(function () {
    this.resource('profile', {path: '/'}, function(){
        this.route('edit');
    });
});

App.ProfileRoute = Ember.Route.extend({
  model: function() {
    return this.store.find('user').then(function(users){
      return users.get('firstObject');
    });
  }
});

App.ProfileEditRoute = App.ProfileRoute.extend({
    deactivate: function(){
        var model = this.modelFor('profile');
        if(model.get('isDirty') && !model.get('isSaving')){
          model.rollback();
        }
    },
    actions: {
        save: function(){
            this.modelFor('profile').save();
            this.transitionTo('profile');
        }
    }
});

App.User = DS.Model.extend({
    email: DS.attr('string')
});

App.User.FIXTURES = [
    {
        id: 1,
        email: 'herpyderp@gmail.com'
    }
];

Updated fiddle: http://jsfiddle.net/kitsunde/3FKg4/2/

OTHER TIPS

The save method returns a promise, you could transition when the promise is resolved as:

var route = this;
profile.save().then(function() {
  route.transitionTo('profile');
}, function() {
  // TODO: implement error logic
});

In that case, your method will be updated when the application goes back to the index state.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top