Reputation: 3317
So I asked a similar question awhile back. However, something about that solution left a bad smell.
Here's the scenario, when I want to create a record I have a new route. So for example PostsNewRoute
that looks something like:
App.PostsNewRoute = Ember.Route.extend({
model: function() {
return App.Post.createRecord({title: '', content: ''});
},
deactivate: function() {
var controller = this.controllerFor('posts.new');
var content = controller.get('content');
if (content && content.get('isNew') && !content.get('isSaving')) {
content.deleteRecord();
}
}
});
and similarly for PostsEditRoute
:
App.PostsEditRoute = Ember.Route.extend({
model: function(params) {
return App.Post.find(params.post_id);
},
deactivate: function() {
var controller = this.controllerFor('posts.edit');
var content = controller.get('content');
if (content && content.get('isDirty') && !content.get('isSaving')) {
content.rollback();
}
}
});
This didn't seem right to me. I feel that there is too much code to handle this, and in a bigger application where I'm doing this for many objects...
So here is a different approach I tried, which seemed a little cleaner, but had it's own issues (see after the jump):
App.PostsNewRoute = Ember.Route.extend({
model: function() {
return App.Post.createRecord({title: '', content: ''});
}
});
App.PostsEditRoute = Ember.Route.extend({
model: function(params) {
return App.Post.find(params.post_id);
}
});
App.PostsFormView = Ember.View.extend({
templateName: 'posts/form',
tagName: 'form',
classNames: ['form-horizontal'],
buttonText: '',
submit: function() {
// TODO: validation
this.get('controller').get('store').commit();
this.get('controller').transitionToRoute('posts.index');
},
cancel: function() {
var content = this.get('controller').get('content');
if(content && !content.get('isSaving')) {
if(content.get('isNew')) {
content.destroyRecord();
} else if(content.get('isDirty')) {
content.rollback();
}
}
this.get('controller').transitionToRoute('posts.index');
}
});
Template:
<div class="control-group">
<label class="control-label">Title:</label>
<div class="controls">
{{view Ember.TextField valueBinding='title'}}
</div>
</div>
<div class="control-group">
<label class="control-label">Content:</label>
<div class="controls">
{{view Ember.TextArea valueBinding='content'}}
</div>
</div>
<div class="form-actions">
<button class="btn btn-primary">{{view.buttonText}}</button>
<a href="#" class="btn btn-danger" {{action cancel target='view'}}>Cancel</a>
</div>
This works almost the same as what I tried before, however, now if a user clicks on a nav link or clicks the back button stuff doesn't get cleaned up.
Both of these ways don't seem quite right, what would be the right or better way to handle this?
Upvotes: 2
Views: 905
Reputation: 808
well, i liked what i found in this nice little gist (the interesting part is close to the bottom).
following that example, (part of) my PostsNewController
looks like this:
startEditing: function() {
this.transaction = this.get('store').transaction();
this.set('content', this.transaction.createRecord(EmberBlog.Post, {}));
},
stopEditing: function() {
if (this.transaction) {
this.transaction.rollback();
this.transaction = null;
}
}
and my PostsNewRoute like this:
EmberBlog.PostsNewRoute = Ember.Route.extend({
model: function() {
return null;
},
setupController: function(controller) {
controller.startEditing();
},
deactivate: function() {
this.controllerFor('posts.new').stopEditing();
}
});
i think it should be easy enough to adapt to your specific needs.
Upvotes: 2