Backbone View receiving regular object instead of model - javascript

Here I am passing a model to a Backbone view.
view = new View ({model:{item:4,name:"Ipad"}});
When I console.log that model from within the View. I get:
Object {item: 4, title: "Ipad"}
This is not a backbone model therefore I don't have methods
like toJSON. I realize that if I define a Backbone model and
passed it in everything works fine.
view = new GenreView ({model:new Model({title: 4, title: "Ipad"})});
This logs
r {cid: "c2", attributes: Object, _changing: false, _previousAttributes: Object, changed: Object…}
Why is it that first approach doesn't work and how can I fix it?

Its simply that the special 'model' option expects a Backbone.Model not a javascript object.
So you are correct when you create a new Backbone.Model to pass into the view.
There is nothing to fix as far as I can tell.

You need to use a Backbone.Model instead of a regular JavaScript object {}
var Item = Backbone.Model.extend({
// ...
});
Instantiate the Item model
var myItem = new Item();
Now use your item in the view
var myView = new View({model: myItem});
This answer assumes that View is setup as something like
var View = Backbone.View.extends({
// ...
});

You could cast the object to a Backbone Model in your view's initialize method:
var View = Backbone.View.extend({
initialize: function(options){
if (_.isPlainObject(this.model)) {
this.model = new Backbone.Model(this.model);
}
}
});
This way the view will be able to operate on it's model regardless of whether you passed it an instance of a Backbone.Model or a plain object. You can see an example of it working here: http://jsbin.com/igecEgE/1/edit?js,console

Related

Creating a new collection inside existing collection

I am currently trying to put a backbone model inside an already existing model. I was wondering if this is even possible.
var rf = this.collection.create(attrs, options);
Model.set(table, rf);
Thanks
What you trying to do is "Nested Models & Collections". Backbone already has preferable approach. The common idea consist in storing of nested model directly in the instance of another model instead attributes.
So, you could create child model first and then pass it to parent model through options like the following:
var rf = this.collection.create(attrs, options);
var Model = Backbone.Model.extend({
initialize: function(attributes, options) {
_.isObject(options) || (options = {});
if (options.child) {
this.child = new options.child;
}
}
});
var model = new Model({}, {child: rf});
If you want to get a fully supported tree-like Backbone models you could try to use one of the following plugins.
Hope this helps!

Right way to call a model within a view in Backbone (not using RequireJS)

The goal
Call UserModel within AuthenticationView with Backbone + Sprockets.
The problem
I just don't know a good way to do that.
The scenario
This is my view (assets/js/views/AuthenticationView.js):
var AuthenticationView = Backbone.View.extend({
el: $('.authentication-form'),
events: {
'keyup input[name=email]' : 'validationScope',
'keyup input[name=password]' : 'validationScope',
'submit form[data-remote=true]' : 'authenticate'
},
render: function() {
},
authenticate: function() {
// Here I'm going interact with the model.
}
});
And that's my model (assets/js/models/UserModel.js):
var UserModel = Backbone.Model.extend({
url: '/sessions'
});
The question
How can I make the interaction between the view and the model?
Remember: they're in separated files.
Getting the constructors together would be step 1 -- separate files don't matter, you can use Browserify/requirejs or just throw these things in global scope. From there, since passing an object into a view constructor with the property name 'model', automatically assigns the value to the view's this.model. So if we have an initialize method in our view, we can see:
initialize: function (options) {
console.log(this.model); // User instance
this.model.on('update', function () {});
}
And so we can pass in an instantiated model into the view via an object's model property:
var model = new UserModel();
var view = new AuthenticationView({ model: model });
http://www.joezimjs.com/javascript/lazy-loading-javascript-with-requirejs/ here is great article about js modules lazy loading with examples used backbonejs and requirejs

Setting and getting models by CID in Backbone

I have this collection:
App.Collection.Pieces = Backbone.Collection.extend({
model: App.Model.Piece,
initialize: function() {
this.add(
// The `King` model extends the `Piece` model
new App.Model.King({
cid: 'wk',
color: 'white'
})
);
}
});
Then I have this code in a view:
this.white = new App.Collection.Pieces();
console.log(this.white.get('wk'));
I have two questions:
Can I add a model B to a collection of A models, if B extends A?
The console.log statement returns undefined. Any reason why the cid property is not being set?
Thanks.
You can add any object or model to a collection. If its a plain JS object, the model defined for the collection will be instantiated. Annotated source
According to Backbone's documentation the cid is automatically assigned to all models created. Looking at the annotated source it seems the cid is automatically generated - you cannot assign a custom cid to a model.

Collection in Backbone Model undefined even though instantiated in initialize function

In the Backbone model below I have a nested Backbone collection.
var Student = Backbone.Model.extend({
firstName: null,
lastName: null,
initialize: function() {
this.programCollection = new ProgramCollection({});
}
});
var ProgramCollection = Backbone.Collection.extend({
model: Program
});
However when trying to add Program objects to collection like so...
var testStudent = new Student();
testStudent.get("programCollection").add(new Program());
I get the following error:
Unable to get value of the property 'add': object is null or undefined
Obviously I'm doing something the wrong way since the programCollection is undefined.
Properties of the model instance directly are not the same as attributes properties. If you want a model instance to have a collection, which is not data to be stored directly on that student record, set it as a model instance property (as you are doing) but then just access it directly without calling get.
var testStudent = new Student();
testStudent.programCollection.add(new Program());

Backbone: How To Bind A Model To A View

So I have some objects extended from Backbone.js:
var MyModel = Backbone.Model.extend({});
var modelInstance = new MyModel();
var MyModelView = Backbone.View.extend({});
And I'm trying to figure out how to bind my Model to its corresponding View. How does one handle data-binding in Backbone?
You pass your model instance into the view when creating it.
var modelView = new MyModelView({model: modelInstance})
From the docs:
When creating a new View, the options you pass — after being merged into any default
options already present on the view — are attached to the view as this.options
for future reference. There are several special options that, if passed, will be
attached directly to the view: model, collection, el, id, className, tagName and attributes.

Categories

Resources