I have an app which at the moment contains a view of objects of the same model. They are retrieved from the server, looped through and added to the list controller using an add method
<script>
App.Controllers.List = Em.ArrayProxy.create({
content: Ember.A([]),
add: function(obj){
this.pushObject(obj);
}
});
</script>
I am now working on a part where the user creates a new object that (after passing validation) will be added to the list and also sent to the server.
I can't find any examples on the best patter to follow for creating a new object via an input form. I can see a few options, and have semi-implemented a few but nothing feels right.
I can kind of fight out the functionality I want, but I'd prefer make sure I am aware of best practice.
I currently have something like this (which is the second bullet on my list)
<script>
App.Views.ItemCreate = Em.View.extend({
content: App.Models.Item.create({}),
templateName: 'create',
createButton: function(){
var itemObj = this.get('content');
var item = {};
item.title = this.get('content').get('title');
$.ajax({
type: 'POST',
url: '/test/data.json',
data: item,
dataType: 'json',
success: function(responseData, textStatus, jqXHR) {
App.Controllers.List.add(itemObj);
}
});
}
});
</script>
<script type="text/x-handlebars" data-template-name="create">
{{view Em.TextField id="create-title" valueBinding="content.title"}}
<a href="#" {{action "createButton" }}>Create</a>
</script>
Any help greatly appreciated
NOTES
I've changed the correct answer to pangratz's. Although the other responses directly answered my question, I believe those who find this via Google should refer to the answer Pangratz provided as not only is it good MVC, but it is more Ember-y :o)
In Ember. js, controllers allow you to decorate your models with display logic. In general, your models will have properties that are saved to the server, while controllers will have properties that your app does not need to save to the server.
In Ember Data, models are objects that represent the underlying data that your application presents to the user. Note that Ember Data models are a different concept than the model method on Routes, although they share the same name.
Ember uses templates to organize the layout of HTML in an application. Ember templates use the syntax of Handlebars templates. Anything that is valid Handlebars syntax is valid Ember syntax. Here, {{name}} is a property provided by the template's context.
Ember. js is a MVC (Model–View–Controller) JavaScript framework which is maintained by the Ember Core Team (including Tom Dale, Yehuda Katz, and others).
Communicating with the server is definitely something which shouldn't be done in the view. This is something a controller is for. To separate the different parts of the application further, I would even consider implementing a DataSource
which handles the AJAX requests. This split makes your application more testable and each components reusable. The concrete connections of view, controller and data source are then realized via bindings.
The workflow for your case could be the following:
You should also look at ember-data which is a client side data storage and handles all the boilerplate for you. Also have a look at The architecture of Ember.js apps - data and EmberJS: Good separation of concerns for Models, Stores, Controllers, Views in a rather complex application?
View:
App.View.ItemCreate = Ember.View.extend({
templateName: 'create',
createObject: function(evt) {
var object = this.get('content');
var controller = this.get('controller');
controller.createObject(object);
}
});
Controller:
App.Controllers.List = Ember.ArrayProxy.extend({
content: [],
createObject: function(hash) {
var dataSource = this.get('dataSource');
dataSource.createObject(hash, this, this.createdObject);
},
createdObject: function(object) {
this.pushObject(object);
}
});
DataSource:
App.DataSource = Ember.Object.extend({
createObject: function(hash, target, callback) {
Ember.$.ajax({
success: function(data) {
callback.apply(target, data);
}
});
}
});
Glue everything together:
App.dataSource = App.DataSource.create();
App.listController = App.Controllers.List.create({
dataSourceBinding: 'App.dataSource'
});
App.View.ItemCreate.create({
controllerBinding: 'App.listController'
}).append();
If you want to follow a strict MVC model then the model should never be created on the view but on the controller. Ember is still very young and still haven't any defined patterns, what I would do is have your model set as the content of the view (as you have already done) with all the inputs bind to the different model attributes. Then when the button is pushed:
createButton: function(){
App.Controllers.List.create(this.get('content'));
}
On the controller:
create: function(model) {
if model.valid() { //validates the model
model.save({
onSuccess: function(response) { // callback
var item = App.Models.Item.create(response.item)
App.controllers.List.add(item)
}
})
}
And finally the model:
save: function(options) {
$.ajax({
type: 'POST',
url: '/test/data.json',
data: item,
dataType: 'json',
success: options.onsuccess
});
}
This is the way other js frameworks expect you to work. It feels a little more verbose and complex, but it keeps the things in place
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With