how to access a models data from a view in backbone.js - backbone.js

I have a model named person:
var person = Backbone.Model.extend({
initialize: function(){
console.log('cool');
},
defaults:{
names:['a','k','d','s','h','t']
}
})
Now I have a view:
var person_view = Backbone.View.extend({
model : person,
output: function(){
console.log(this.model.get('names'))
}
});
Created an object of the view:
var obj = new person_view()
Try to access names:
obj.output()
But I got this error:
TypeError: Object function (){ parent.apply(this, arguments); } has no method 'get'
Can you show me how to do things properly?I've only just started getting to know backbone.js so please bear with me.

You have to initialize your Model before you could access it :
var person_view = Backbone.View.extend({
initialize: function() {
this.model = new person();
},
output: function(){
console.log(this.model.get('names'))
}
});

Instead of passing the model when you extend the view, you'll want to pass it when you construct a new view:
var person_view = Backbone.View.extend({
output: function(){
console.log(this.model.get('names'))
}
});
var obj = new person_view({
model : new person()
});

Your "person_view" can not access any model (which is expected by that view) ,as no model is created yet, when you are declaring "person_view" and calling its function.
First make a model then pass it to view when declaring that "person_view".
var model_person_for_view= new person();
var obj = new person_view(model:model_person_for_view);
obj.output();

Related

My model attribute in my view is being classified as a function

So I am trying to link my view to my model and I am following the instructions perfectly, however when it comes to the model part I am just stumped.
Whenever I try to define the model via instantiation, the model is being classified as a function when I console.log() it out.
But let me show you.
var ListModel = Backbone.Model.extend({
defaults: {
name: "Miles",
last: "Coleman"
}
});
var ListView = Backbone.View.extend({
initialize: function(opts){
this.template = opts.template;
this.render();
},
render: function() {
var data = this.model.toJSON();
console.log(this.model);
// outputs: function (){a.apply(this,arguments)}
}
});
var view = new ListView({
model: ListModel,
el: 'div',
template: _.template('#todo-template')
});
Is there some silly detail that I'm missing here? Thanks!
You're passing the class itself, ListModel, to the view, but a view expects an instance of the class, new ListModel() for example. Try
var view = new ListView({
model: new ListModel(),
el: 'div',
template: _.template('#todo-template')
});
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript for more information on classes and instances in JS.

Backbone call a model method from the view

I have a backbone app with require where I want to add a collection inside a collection with a method inside model.
I have tried to insert the method in the collection but I can't add elements.
I'd want to make a collection of app when I click an element outside the app I want add inside my app other app in a collection.
This is my app:
Model:
define(['backbone', 'collections/element'],function(Backbone, ElementCollection){
var DesignModel = Backbone.Model.extend({
initialize:function(){
console.log('Initialized Design model');
_.defaults(this, {
elements: new ElementCollection()
});
},
addElement: function(elements, options) {
return this.elements.add(elements, options);
}
});
return DesignModel;
});
Collection:
define(['backbone', 'models/design'], function(Backbone, DesignModel){
var designCollection = Backbone.Collection.extend({
model: DesignModel,
});
return designCollection;
});
View
define(['jquery' , 'backbone', 'models/design', 'collections/design', 'views/element'],
function($, Backbone, DesignModel, DesignCollection, ElementView){
var DesignView = Backbone.View.extend({
el:$('#page'),
initialize: function(){
console.log('initialize DesignView');
this.collection = new DesignCollection();
var here = this;
$('#insert-dynamic-element').click(function(){
var element = new ElementView();
here.collection.models.addElement(element);
});
},
render: function(){
}
})
return DesignView;
});
I have tried to call the function addElement in this way:
here.collection.models.addElement(element);
and
here.collection.addElement(element);
But always with error that Object has no method addElement
How can I solve this? I want to call the method addElement from the view to add an app inside another app in a collection.
Thanks
The safest way to call the method is to add the method to the collection instead of the Model. Currently the method is available on the Model instance .
So this.collection.models.addElement will not cut it
Collection
define(['backbone', 'models/design'], function(Backbone, DesignModel){
var designCollection = Backbone.Collection.extend({
model: DesignModel,
addElement: function(elements, options) {
return this.add(elements, options);
}
});
return designCollection;
});
View
define(['jquery' , 'backbone', 'models/design', 'collections/design', 'views/element'],
function($, Backbone, DesignModel, DesignCollection, ElementView){
var DesignView = Backbone.View.extend({
el:$('#page'),
initialize: function(){
console.log('initialize DesignView');
this.collection = new DesignCollection();
var here = this;
$('#insert-dynamic-element').click(function(){
var element = new ElementView();
here.collection.addElement(element);
});
},
render: function(){
}
})
return DesignView;
});
If you do not want to move the method from the current model. Then you might have to call a specific model using the index
here.collection.at(0).addElement(element);
But there might be a case when there are no model in the collection and this might lead to a error condition..
here.collection.at(0) && here.collection.at(0).addElement(element);
Well, you need to get a specific model, not the array of them. This seems like an error since you'll be picking a specific model essentially arbitrarily (unless you application has semantics that support this), but this would work:
here.collection.at(0).addElement(element);

Show Collection Data in View In Backbone.js

I am new to backbone.js. I have 2 javascript files. 1 for collection and 1 for view.
**collection.js**
var colle = Backbone.Collection.extend({
initialize: function () {
var data = [
{ Name: "a", Image: "path1" },
{ Name: "b", Image: "path2" },
];
}
});
and my view.js is
var View = Backbone.View.extend({
initialize: function () {
this.collection = colle;
},
render:function(){
//How can I access that data here ?
}
});
var view1 = new View();
How can I access my Collection data in View ?
Thank you.
First, you need an instance of your collection - currently you've defined colle as a constructor for a Backbone collection when what you need now is an instance:
var myCollection = new colle(); // convention is to use uppercase when defining your constructor
then, pass a reference to your collection when you instantiate your view:
var view1 = new View({ collection: myCollection });
then, inside your view you can reference your collection using this.collection:
render: function () {
// reference your collection using this.collection here
}
If you can be more specific about what you want to do with your collection, I can expand the example to demonstrate something more useful.

backbone.js - Undefined is not a function

I've started learning Backbone.js and tried to write my first app with Collections. Here is the code:
console.clear();
(function($){
window.App = {
Models : {},
Collections : {},
Views : {}
};
//a single estimate
App.Models.Estimate = Backbone.Model.extend({});
// multiple esitmates
App.Collections.Estimates = Backbone.Collection.extend({
model : App.Collections.Estimate
});
App.Views.Estimates = Backbone.View.extend({
tagName: 'ul',
render : function(){
this.collection.each(this.addTo,this);
},
addTo:function(estimate){
var dir = App.Views.Estimate({model:estimate}).render();
this.$el.append(dir.el);
}
});
App.Views.Estimate = Backbone.View.extend({
tagName: 'li',
render :function(){
this.$el.html(this.model.get('title'));
return this;
}
});
var jSon = [{title:'Abhiram', estimate:8}];
var estimates = new App.Collections.Estimates(jSon);
console.log(estimates);
var tasksView = new App.Views.Estimates({collection:estimates});
// var a = tasksView.render().el;
//console.log(a);
})($j||jQuery);
I've all the three included :
jQuery first, Underscore next and Backbone. I keep getting "Undefined is not a function".Please let me know if i am doing anything wrong.
Thanks!
Are you sure that you want to assign collection App.Collections.Estimate as model to it self?
// multiple esitmates
App.Collections.Estimates = Backbone.Collection.extend({
model : App.Collections.Estimate
});

Backbone.js model property is getting not defined error

I'm very new to Backbone.js and am trying to get this simple example working. Basically, in jsFiddle when I run the code it tells me that the property "firstname" is not defined.
Here's a link to the fiddle:
http://jsfiddle.net/cpeele00/YjUBG/16/
var User = Backbone.Model.extend({});
var UserList = Backbone.Collection.extend({
model: User
});
var UserView = Backbone.View.extend({
el: $('#user-list ul'),
template: _.template($('#user-list-template').html()),
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
var user1 = new User();
user1.set({
firstname: 'Momo',
lastname: 'Peele'
});
var user2 = new User();
user2.set({
firstname: 'Bobo',
lastname: 'Peele'
});
var users = new UserList([user1, user2]);
var userView = new UserView({model: users});
userView.render();
​
Any help figuring this out would be greatly appreciated.
V/R
Chris
Since the model is actually a collection, you need to iterate over it, and apply the template to each model in the collection. One way is to use the Underscore extension Collection.each:
render: function() {
// clear the view
this.$el.empty();
// save a reference to the view object
var self = this;
// iterate over the collection
this.model.each(function(singleModel) {
// render the model
self.$el.append(self.template(singleModel.toJSON()));
});
return this;
}
Here's the updated Fiddle.
(You could also put the iteration into the template itself if you like, but I think it's generally preferable to keep code in the view, rather than the template.)

Resources