Dynamically pass urlRoot to backbone.js model - javascript

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

Related

How to handle empty and full objects in a Knockout ViewModel

I can't seem to find the answers I am looking for on stack. Maybe my scenario is just wrong but I'm going to ask the question anyway. I have a form which serves two purposes... Create new user and View User. Both have the same view model User. So let's look at my viewmodel:
var UserModel = function() {
var self = this;
self.UserId = ko.observable();
self.FirstName = ko.observable();
self.LastName = ko.observable();
self.FirstName.extend({required: true});
return self;
}
So my bindings are configured at a higher level, I have a viewmodel with a property called User. this property called User is bound to my form. For the simple scenario of creating a new user I would call:
this.User(new UserModel());
Note: this.User is observable, hence the brackets.
this will successfully create my user model with a blank form and all validation works.
Ok so scenario two! I get an full object from the API, how should I map this. If I use:
this.User(ko.mapping.fromJS(data, {}, UserModel));
the validation doesn't work. I have seen the mapping options which include the create method, but how do I use this without losing the functionality at the top?!
As a side note to make it a little more complicated:
User.ConfirmEmail exists in my viewmodel but not on the server! So that is my next hurdle. If I use the create mapping I know I can easily add it.
My Current Working Example
By using lots of constructor parameters I can accomplish both:
var UserModel = function(id, fname, lname) {
var self = this;
self.UserId = ko.observable(id);
self.FirstName = ko.observable(fname);
self.LastName = ko.observable(lname);
self.FirstName.extend({required: true});
return self;
}
If I now use, new UserModel() it still sets the properties up and I can also pass through the values. It just looks bad :(
Separate the creation of the user from the adding of the validation rule:
function userFactory(user) {
if (typeof user === 'undefined') {
user = new User();
}
user.firstName.extend({required: true});
}
Then you can do this:
var newUser = userFactory(ko.mapping.fromJS(data, {}, new UserModel()));
this.user(newUser);
... and keep the Validation.

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

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

Categories

Resources