Accessing model ID in backbone.js - javascript

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 :)

Related

Dynamically pass urlRoot to backbone.js model

Using backbone.js I have a special case where I need to dynamically pass in the actual urlRoot to the model when creating it.
This is what I have tried with no luck:
var reward = new Reward({urlRoot: campaign.get('url_created')});
var Reward = Backbone.Model.extend({
urlRoot: urlRoot
});
Does Model.extend have any options for me to pass my url_created string. I have tried using ID option and leaving urlRoot blank but this will not work.
You can specify a function that returns the urlRoot that will return the value, one way to pass it through is shown below,
var Reward = Backbone.Model.extend({
urlRoot: function(){ return this.get('url_created') },
});
var reward = new Reward({'url_created': campaign.get('url_created')});

Backbone: Id not being set to model

I have tried the following to set an id to my model:
var globalCounter = 1;
var Model = Backbone.Model.extend({
initialize: function () {
this.id = globalCounter;
globalCounter += 1;
}
});
myModel = new Model();
console.log(myMode.get('id')); // prints undefined
How can I set an id to my models?
You need to use the set() function instead (http://jsbin.com/agosub/1/);
var globalCounter = 1;
var Model = Backbone.Model.extend({
initialize: function () {
this.set('id', globalCounter);
globalCounter += 1;
}
});
myModel = new Model();
console.log(myModel.get('id')); // prints 1
You must use :
this.set('id', globalCounter);
instead of this.id = globalCounter;
You are adding the id value to the Model object, but you want to add it to Model.attributes object. And that what is doing Model.set() method.
model.set("key", value) will put the value in model.attributes.key;
model.get("key") will return the value inside model.attributes.key
This is a little weird for new comers to Backbone, but it's a major (and easy) point to get. It's designed so that using model.set(...) will fire change events you can easily catch to update your views.
Backbone and ES6 Update :
The Backbone attribute object is outdates by ES6 getters and setters. Theses functions can overwrite the standard access.
Warning : this is pseudo-code that may be one day used with ES6 !
class MyModel extends Backbone.Model{
get id(){ return this.attributes.id; }
set id(id){ this.attributes.id = id; }
}
This would allow to write :
let myModel = new Model();
myModel.id = 13; // will use myModel.id(13)
console.log (myModel.id); // will show myModel.id()
As of today, this is only a dream of a Backbone 2. After basic searches, I've seen nothing about that coming.

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

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

Fetch data having a specific id defined in the view instance

I need to fetch data having a specific id
and which id is defined in the view instance.
Here the example, see the comments in MyModel definition:
// my view instance
var myView = new MyView({
model: {id: 12321}
});
MyView = Backbone.View.extends({
initialize: function()
{
myModel.fetch();
}
});
MyModel = Backbone.Model.extends({
url: function url ()
{
// how to get the id passed to view instance?
return "http:..../id/" + this.id;
}
});
Model should not has any knowledge of the existence of the View, so the View should be the one that sais to the Model which id to fetch:
MyView = Backbone.View.extends({
initialize: function()
{
myModel.id = this.model.id;
myModel.fetch();
}
});
(I've used your example code as template for my example, but I have to say I feel several weird things on it, I suppose is just a matter of taste)
Update: My very personal taste opinions
Is very difficult to do this but as you requested I'll share with you my very personal code review of your example code. Take this as it is: a very humble opinion.
this.model confused
I would not use attribute names that can create confussion:
var myView = new MyView({
model: {id: 12321}
});
Into this instance this.model is making reference to a raw Hash but in a Backbone context this is against the intuitive feeling that this is gonna be a Backbone.Model.
I rather change it for something like this:
var MyView = Backbone.View.extend({
initialize: function( opts ){
this.model_id = opts.model_id;
}
})
var myView = new MyView({ model_id: 12321 });
I think this naming is more intuitive.
close variables scopes
This code can only works if myModel is in an scope bigger that it should be:
MyView = Backbone.View.extends({
initialize: function()
{
myModel.fetch();
}
});
I rather prefer using more encapsulated scopes, even if myModel has been declared in the out-side context of your View the View should use a variable of its private context. For example
var MyView = Backbone.View.extends({
initialize: function( opts ) {
this.model = opts.model;
this.model.fetch();
}
});
var myView = new MyView({ model: myModel });
Check the detail that I have also added var in front of MyView because if not MyView will be a window global variable.
use the Backbone urlRoot
In your example, this ...
MyModel = Backbone.Model.extends({
url: function url ()
{
// how to get the id passed to view instance?
return "http:..../id/" + this.id;
}
});
... can be summarized as this:
MyModel = Backbone.Model.extends({
urlRoot: "http:..../id"
});

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);

Categories

Resources