I am consoling the height, while it get changed, as well i am binding the change event to the element. still i am not getting the console output here...
i am very new to backbone, any one correct my mistake?
var Person = Backbone.Model.extend({
initialize:function(){
var getHeight = prompt('provide your height');
this.set({height:getHeight}); //i am changing the height...
this.bind('change:height',function(){
console.log(this.get('height')); //i am not getting any console here...
})
},
defaults:{
name:'new Name',
height:'unknown'
}
});
var person = new Person();
Set the value after the binding if you want to monitor the event:
var Person = Backbone.Model.extend({
initialize:function(){
// bind is deprecated
this.on('change:height',function(){
console.log(this.get('height'));
});
var getHeight = prompt('provide your height');
this.set({height:getHeight});
},
defaults:{
name:'new Name',
height:'unknown'
}
});
Related
I am trying to receive a json data and append to element. all are work fine up to i use the static assignments. while i start to fetch the data from server side, or using fetch nothing work for me.. something wrong with my fech process, any can help me to correct my fetch process and update my code.(instead of simply placing the correct code)..
my JSON(sample):
nameing = [
{name:'student4'},
{name:'student5'},
{name:'student6'}
]
Backbone code:
(function($){
var list = {};
list.model = Backbone.Model.extend({
defaults:{
name:'need the name'
}
});
list.collect = Backbone.Collection.extend({
model:list.model,
url : 'data/names.json', //this is correct path.
initialize:function(){
this.fetch();
}
});
list.view = Backbone.View.extend({
initialize:function(){
this.collection = new list.collect();
this.collection.on("reset", this.render, this);
},
render:function(){
_.each(this.collection.models, function(data){
console.log(data); // i am not get any model here... any one correct my code?
})
}
});
var newView = new list.view();
})(jQuery)
thanks in advance.
Your JSON is not valid. Wiki
[
{"name":"student4"},
{"name":"student5"},
{"name":"student6"}
]
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.)
When the view is initialized, how can I bind the model to the specific View that is created? The view is current initialized at the start of the application. Also, how can I bind the model to the collection?
(function ($) { //loads at the dom everything
//Creation, Edit, Deletion, Date
var Note = Backbone.Model.extend({
defaults: {
text: "write here...",
done: false
},
initialize: function (){
if(!this.get("text")){
this.set({"text": this.default.text});
}
},
edit: function (){
this.save({done: !this.get("done")});
},
clear: function (){
this.destroy();
}
});
var NoteList = Backbone.Collection.extend({
model:Note
});
var NoteView = Backbone.View.extend ({
el: "body",
initialize: function(){
alert("initialized");
var list = new NoteList;
return list;
},
events: {
"click #lol" : "createNote"
},
createNote : function(){
var note = new Note;
this.push(note);
alert("noted");
}
});
var ninja = new NoteView;
})(jQuery);
Update
I just took a look at #James Woodruff's answer, and that prompted me to take another look at your code. I didn't look closely enough the first time, but I'm still not sure what you're asking. If you're asking how to have a model or view listen for and handle events triggered on the other, then check out James's example of calling bind() to have the view listen for change (or change:attr) events on the model (although I'd recommend using on() instead of bind(), depending what version of Backbone you're using).
But based on looking at your code again, I've revised my answer, because I see some things you're trying to do in ways that don't make sense, so maybe that's what you're asking about.
New Answer
Here's the code from your question, with comments added by me:
var NoteView = Backbone.View.extend ({
// JMM: This doesn't make sense. You wouldn't normally pass `el`
// to extend(). I think what you really mean here is
// passing el : $( "body" )[0] to your constructor when you
// instantiate the view, as there can only be one BODY element.
el: "body",
initialize: function(){
alert("initialized");
// JMM: the next 2 lines of code won't accomplish anything.
// Your NoteList object will just disappear into thin air.
// Probably what you want is one of the following:
// this.collection = new NoteList;
// this.list = new NoteList;
// this.options.list = new NoteList;
var list = new NoteList;
// Returning something from initialize() won't normally
// have any effect.
return list;
},
events: {
"click #lol" : "createNote"
},
createNote : function(){
var note = new Note;
// JMM: the way you have your code setup, `this` will be
// your view object when createNote() is called. Depending
// what variable you store the NoteList object in (see above),
// you want something here like:
// this.collection.push( note ).
this.push(note);
alert("noted");
}
});
Here is a revised version of your code incorporating changes to the things I commented on:
var NoteView = Backbone.View.extend( {
initialize : function () {
this.collection = new NoteList;
},
// initialize
events : {
"click #lol" : "createNote"
},
// events
createNote : function () {
this.collection.push( new Note );
// Or, because you've set the `model` property of your
// collection class, you can just pass in attrs.
this.collection.push( {} );
}
// createNote
} );
var note = new NoteView( { el : $( "body" )[0] } );
You have to bind views to models so when a model updates [triggers an event], all of the corresponding views that are bound to the model update as well. A collection is a container for like models... for example: Comments Collection holds models of type Comment.
In order to bind a view to a model they both have to be instantiated. Example:
var Note = Backbone.Model.extend({
defaults: {
text: "write here..."
},
initialize: function(){
},
// More code here...
});
var NoteView = Backbone.View.extend({
initialize: function(){
// Listen for a change in the model's text attribute
// and render the change in the DOM.
this.model.bind("change:text", this.render, this);
},
render: function(){
// Render the note in the DOM
// This is called anytime a 'Change' event
// from the model is fired.
return this;
},
// More code here...
});
Now comes the Collection.
var NoteList = Backbone.Collection.extend({
model: Note,
// More code here...
});
Now it is time to instantiate everything.
var Collection_NoteList = new NoteList();
var Model_Note = new Note();
var View_Note = new NoteView({el: $("Some Element"), model: Model_Note});
// Now add the model to the collection
Collection_NoteList.add(Model_Note);
I hope this answers your question(s) and or leads you in the right direction.
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();
I've been staring at this for a while and trying various tweaks, to no avail.
Why am I getting a "this.model is undefined" error at
$(function(){
window.Sentence = Backbone.Model.extend({
initialize: function() {
console.log(this.toJSON())
}
});
window.Text = Backbone.Collection.extend({
model : Sentence,
initialize: function(models, options){
this.url = options.url;
}
});
window.SentenceView = Backbone.View.extend({
initialize : function(){
_.bindAll(this, 'render');
this.template = _.template($('#sentence_template').html());
},
render : function(){
var rendered = this.template(this.model.toJSON());
$(this.el).html(rendered);
return this;
}
})
window.TextView = Backbone.View.extend({
el : $('#notebook') ,
initialize : function(){
_.bindAll(this, 'render');
},
render : function(){
this.collection.each(function(sentence){
if (sentence === undefined){
console.log('sentence was undefined');
};
var view = new SentenceView({model: sentence});
this.$('ol#sentences').append(view.render().el);
});
return this;
}
});
function Notebook(params){
this.text = new Text(
// models
{},
// params
{
url: params.url
}
);
this.start = function(){
this.text.fetch();
this.textView = new TextView({
collection: this.text
});
$('body').append(this.textView.render().el);
};
}
window.notebook = new Notebook(
{ 'url': 'js/mandarin.js' }
);
window.notebook.start();
})
There's an online version wher eyou can see the error in a console at:
http://lotsofwords.org/languages/chinese/notebook/
The whole repo is at:
https://github.com/amundo/notebook/
The offending line appears to be at:
https://github.com/amundo/notebook/blob/master/js/notebook.js#L31
I find this perplexing because as far as I can tell the iteration in TextView.render has the right _.each syntax, I just can't figure out why the Sentence models aren't showing up as they should.
var view = new SentenceView({model: sentence});
I'm pretty sure when you pass data to a backbone view constructor, the data is added to the Backbone.View.options property.
Change this line
var rendered = this.template(this.model.toJSON());
to this
var rendered = this.template(this.options.model.toJSON());
and see if it works
UPDATE:
From the doco:
When creating a new View, the options you pass 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, and tagName
So, disregard the above advice - the model should by default be attached directly to the object
Things to check next when debugging:
confirm from within the render() method that this is actually the SentenceView object
confirm that you are not passing in an undefined sentence here:
var view = new SentenceView({model: sentence});
UPDATE2:
It looks like the collection is borked then:
this.textView = new TextView({
collection: this.text
});
To debug it further you'll need to examine it and work out what's going on. When I looked in firebug, the collection property didn't look right to me.
You could have a timing issue too. I thought the fetch was asynchronous, so you probably don't want to assign the collection to the TextView until you are sure it has completed.
Backbone surfaces underscore.js collection methods for you so you can do this. See if this works for you:
this.collection.each(function(sentence) {
// YOUR CODE HERE
});
I think the problem is on line 48 of notebook.js shown below:
render : function(){
_(this.collection).each(function(sentence){
var view = new SentenceView({model: sentence});
this.$('ol#sentences').append(view.render().el);
});
The problem is you are wrapping the collection and you don't have to. Change it to
this.collection.each(function(sentence){ ...
hope that fixes it
EDIT:
OK i'm going to take another crack at it now that you mentioned timing in one of your comments
take a look at where you are fetching and change it to this:
this.start = function(){
this.text.fetch({
success: _.bind( function() {
this.textView = new TextView({
collection: this.text
});
$('body').append(this.textView.render().el);
}, this)
);
};
I typed this manually so there may be mismatching parentheses. The key is that fetch is async.
Hope this fixes it
try using _.each
_.each(this.collection, function(sentence){
if (sentence === undefined){
console.log('sentence was undefined');
};
var view = new SentenceView({model: sentence});
this.$('ol#sentences').append(view.render().el);
},this);