How to get model name from a collection with backbone.js - javascript

How can i get model name from a collection? When i define a collection, i specify the model attribute as :
Domains = Backbone.Collection.extend({
model : Account
})
How can i get this attribute value?
I tried Domains.model...

First of all I don't think Backbone is gonna work if you use a String to initialize Collection.model, you have to specify a Model class reference like this:
var MyModel = Backbone.Model.extend({});
var MyCollection = Backbone.Collection.extend({
model: MyModel
});
Said that I don't this is possible to retrieve the name of a variable from the variable reference itself.
I suggest to come up with a workaround which is tagging every Model with a String class attribute to which you can ask wich is the name of the class:
var MyModel = Backbone.Model.extend({
name: "MyModel"
});
var MyCollection = Backbone.Collection.extend({
model: MyModel
});
var myCollection = new MyCollection();
console.log( "reference", myCollection.model ); // reference to the class
console.log( "reference.name", myCollection.model.prototype.name );​ // string name
Check the jsFiddle

Related

Accessing model ID in backbone.js

I’m building my first Backbone application, and I’m a little confused with how I pass an ID into a model. When I instantiate the model, I pass in the ID like this var user = new UserModel(id);. At that point, id == 1. The value is still the same in the initialize
method in the model. When I use that variable in the url property, it’s undefined. Why is that?
// Filename: models/user/UserModel.js
define([
'underscore',
'backbone'
], function(_, Backbone) {
var UserModel = Backbone.Model.extend({
initialize: function(id) {
console.log('modelID: ' + id); // Prints 'modelID: 1'
this.set({'id': id});
},
// Sends GET request to http://[domain]/users/view/undefined
url: 'users/view/' + this.id
});
return UserModel;
});
This one works:
var UserModel = Backbone.Model.extend({
initialize: function(id) {
console.log('modelID: ' + id); // Prints 'modelID: 1'
this.set({'id': id});
},
// Sends GET request to http://[domain]/users/view/undefined
url: function(){
return "/users/view/"+this.get("id");
}
});
console.log(new UserModel("10").url())
http://jsfiddle.net/wyA9Q/2/
A Backbone model expects an object representing the attributes as first argument to its constructor
constructor / initialize new Model([attributes], [options])
When creating an instance of a model, you can pass in the initial values of the attributes, which will be set on the model. If you define an initialize function, it will be invoked when the model is created.
Setting model.urlRoot will help build your URLs
urlRoot model.urlRoot or model.urlRoot()
Specify a urlRoot if you're
using a model outside of a collection, to enable the default url
function to generate URLs based on the model id. "[urlRoot]/id"
Attributes should be accessed via model.get
So you could define your model as
var UserModel = Backbone.Model.extend({
urlRoot: '/users/view'
});
and instantiate it as var user = new UserModel({id: id});
var userModel = new UserModel({id: 10});
userModel.fetch();
It should work :)

How to call model's method from collection in backbone.js?

I've been trying to learn backbone.js these days. What I've is a model and a collection. The model has some default properties defined in it which I want to fetch within a collection. This is my code:
var model = Backbone.Model.extend({
defaults : {
done : true
}
});
var collection = Backbone.Collection.extend({
model : model,
pickMe : function () {
log(this.model.get('done')); //return undefined
}
});
var col = new collection();
col.pickMe();
How do I call methods defined in my model from collection? Am I doing wrong here?
The basic setup of Backbone is this :
You have models which are part of collection(s). So here in your setup you have a model constructor model and collection constructor collection, but you have no models in your collection and if you have any models they will be an array, so your code should be something like this
var model = Backbone.Model.extend({
defaults : {
done : true
}
});
var collection = Backbone.Collection.extend({
model : model,
pickMe : function () {
for ( i = 0; i < this.models.length; i++ ) {
log(this.models[i].get('done')); // this prints 'true'
}
}
});
// Here we are actually creating a new model for the collection
var col = new collection([{ name : 'jack' }]);
col.pickMe();
You can check the working jsFiddle here : http://jsfiddle.net/S8tHk/1/
#erturne is correct, you're trying to call a method on your model constructor, not a model instance. That doesn't make sense.
If you really want to define methods on the collection, then #drinchev provides an example of how to iterate through the models in the collection and invoke their methods. Although, the example is rather clunky -- using the built-in iterator methods would be more elegant.
Depending what you're trying to accomplish, you may want to just use the built-in collection iterator methods to invoke methods on each model instead of defining methods on the collection. E.g.:
var Model = Backbone.Model.extend({
defaults : {
done : true
}
});
var Collection = Backbone.Collection.extend({
model : Model
});
var col = new Collection([{}, {done : false}, {}]);
col.each(function (model) {
log(model.get('done'));
});
I think you'd better attach your model methods to the model itself, not in the collection. So you should have somethings like this:
var model = Backbone.Model.extend({
defaults : {
done : true
},
pickMe : function () {
log(this.get('done'));
}
});
var collection = Backbone.Collection.extend({
model : model,
});
var model = collection.get(id)
model.pickMe()

Set backbone model attribute value to another model

Can I set another backbone model as its attribute ?
I have a model that represents a basic entity, I 'd like to reuse it as part of something else.
But, it looks like Backbone's model attribute value can only be String.
Sort answer: yes you can:
myHouse.set({ door: new Door() })
But, in my opinion, is not a good idea to do so, because I don't think Backbone is expecting to found Objects in the Model.attributes. I didn't try but I don't think methods like Model.toJSON are gonna have a correct behavior if someone of the attributes is an Object.
But said so, I don't see any problem to declare real attributes in the Model that make reference to objects like:
myHouse.door = new Door();
If I understood correctly you need to do something like that:
var ModelOne = Backbone.Model.extend({
method : function() {
console.log('ModelOne > method');
},
sayHello : function() {
console.log('ModelOne > hello');
}
});
var ModelTwo = ModelOne.extend({
method : function() {
ModelOne.prototype.method.apply(this);
console.log('ModelTwo > method');
}
});
var methodTwo = new ModelTwo();
methodTwo.method();
methodTwo.sayHello();
Output:
ModelOne > method
ModelTwo > method
ModelOne > hello
One more variation of setting Backbone.Model to the attribute of another model is to set it as default value:
var UserModel = Backbone.Model.extend({
defaults: {
id: null,
name: null,
address: new AddressModel()
}
});
var someUser = new UserModel();
someUser.address.set('country', 'ZA');
When you are doing someUser.save() data enclosed in someUser.attributes.address will be a usual data object.
! One thing not yet tested by me is population of AddressModel upon someUser.fetch()

Add values to a view with JSON and Backbone.js

I have a View (created using Backbone.View.extend) and a JSON object, I actually get the object from a couchdb database. How do I give the values to the view?
For example, I have these two objects:
var personJSON = {"name":"Buddy","email":"trout#fish.net"}
var personDetailsView; //Backbone.View
Is there a way to pass the values into the view without explicitly mapping them to the model?
I've found examples where you can add objects to a Backbone collections but not a view.
If you need to have access to the JSON object within the PersonDetailsView (Backbone.View) object, one way of doing this is to pass the JSON parameter as an option in the View's constructor:
//view definition
var PersonDetailsView = Backbone.View.extend({
initialize: function(){
this.person = this.options.person; //do something with the parameter
}
});
var personJSON = {"name":"Buddy","email":"trout#fish.net"};
var personDetailsView = new PersonDetailsView({ person : personJSON });
From Backbone's official documentation:
When creating a new View, the options you pass are attached to the view as this.options, for future reference.
Usually, you retrieve model via model collection and pass it to view:
var person=personCollection.find(1);
var view=new PersonView({model: person});
var personView = Backbone.View.extend({
template: JST['personTemplate'],
render: function(){
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
$('#container').html(personView.render().el);

How can I pass properties into a Backbone.Model which I do not wish to be treated as attributes?

I have a Backbone.Model named Company.
My Company model has an Employees Backbone.Collection containing Employee models.
When I instantiate my Employee models to populate the Employees collection I wish for them to have a reference to the Company they belong to. But when I pass Company in it becomes one of the attributes of Employee. This is an issue when I go to save the Employee because the toJSON method will contain a Company object, when in the database all I store is the foreign key integer company_id.
I wish there was a second parameter for Backbone.Model that accepted model properties that are not part of the core attributes. How can I get around this? I realize I could instantiate my Employee models and afterwards attach the Company, but I really want to do all the assignments in a traditional "constructor" rather than attach properties from outside.
e.g.:
Employee = Backbone.Model.extend({});
Employees = Backbone.Collection.extend({
model: Employee
});
Company = Backbone.Model.extend({
initialize: function() {
this.employees = new Employees({});
}
});
c1 = new Company({id: 1});
e = new Employee({name: 'Joe', company_id: 1, company: c1});
c1.employees.add(e);
e.get('company'); // => c1
e.save(); // BAD -- attempts to save the 'company' attribute, when in reality I only want to save name and company_id
//I could do
c2 = new Company({id: 2});
e2 = new Employee({name: 'Jane', company_id: 2});
e2.company = c2;
c2.employees.add(e);
e.company; // => c2
//I don't like this second method because the company property is set externally and I'd have to know it was being set everywhere in the code since the Employee model does not have any way to guarantee it exists
You could always read it manually from the options object and store it however you like. The options are passed as the second argument to the initialize method:
var Employee = Backbone.Model.extend({
initialize: function(attributes, options) {
this.company = options.company;
}
});
var shesek = new Employee({name: 'Nadav'}, {company: Foobar});
Alternatively, you can use Backbone-relational which makes it much easier to handle models that contains references to other models and collection.
You might also be interested in making toJSON() recursive (a patch I submitted to their issue tracker)
You can override the save method on the model to convert the save record to only send name and company id.
Employee = Backbone.Model.extend({
save: function() {
var toSend = {name:this.get('name'),company_id: this.get('company').get('id')}
// method to send toSend to server.
}
});

Categories

Resources