开发者

Trouble with Creating Backbone Models & Collections

I'm really, really trying to learn Backbone and it's quite a lot for me to wrap my head around (coming from Rails). So I'm trying to code a simple app that just fetches a collection from a Sinatra backend. Right now, the route /schools returns a JSON object that looks like ["One School", "Two School"]. Pretty simple. Unfortunately, the following always returns ReferenceError for me:

School model

(function() {
   window.school = Backbone.Model.extend({});
}).call(this);

School collection

(function() {
  window.schools = Backbone.Collection.extend({
    url: '/schools',
    model: window.school
  });
}).call(this);

Console

var f = new window.school({name: "temp"});

undefined

f.id();

ReferenceErrror

So simple interactions like this won't work. Also, calling window开发者_开发问答.schools.fetch() results in a UndefinedObject error. Don't know where I went wrong exactly, but nothing seems to be working. Any help would be awesome!

Edit: The collection & model are written in a closure because its compiled from Coffeescript.


There are two ways of getting the model's id: model.id and model.get('id'). model.id() is not defined so it will give you an error. See http://documentcloud.github.com/backbone/#Model-id.


I've never used Coffeescript, however, I'm getting better at backbone... so I'll give it a try. There are a couple of things that may be going on here. backbone.js is reliant on jquery or zepto, and underscore.js, which use the '$' and '_' as their special variables. That may be causing problems with coffeescript.

You might want to get a sample backbone app running instead of trying it with coffeescript.

As far as the code above, there are a couple of things I think I've spotted:

When you instantiate a model with data, it will have no 'id' (since it's not been synced with the server as per the documentation mentioned above). If the data IS from the server, then include an id: id in the init hash, and model.id will return an id. If you need a unique identifier for a model that has NOT been synced, you can use the 'cid' attribute (which is a local, unique identifier).

Remember, when you 'extend' you are actually building a class, so, unless you've instantiated an instance of the collection, a 'fetch' won't work. You'd need to do:

var collection = new Collection();
collection.fetch();

The reason why 'save()' isn't working is because you've not defined a url for the singular model. You've defined it in the collection, but not the model, so if you try to instantiate a non-collection model, it's got no reference to the restful service.

Hope that helps!


f does not have an id because it has not been saved to the server. Backbone has two unique identifiers for every model : one is the clientid which is created the very moment the model is client side. This is not sent to the server. When a model is saved to the server, Backbone expects it to return the JSON encoded saved model, which of course has an id attribute (which it aquires once it is saved in the database) and updates the local model to match the model data sent by server, thereby creating the id attribute on the client model instance. If your server side model does does not correspond exactly to the client side model then you can override Backbone.sync and Backbone.Model.parse functions to suit your requirements.

window.schools.fetch() fails because window.schools is a Collection class and not an instance. Create a collection instance just the way you created a model instance before you fetch and make sure the rails resource schools is correctly configured to send a json encoded list of school model instances. Also if you are going with the out-of-the-box implementation of Backbone.sync , you will have to set : ActiveRecord::Base.include_root_in_json = false

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜