How do I pass the name variable from the router to the FriendInfocollection? Anytime I browse to localhost/app/person/MyName console.log returns a 404 for localhost/slim/index.php/person/
Can someone point me in the right direction on sharing this variable with the collection so it uses the correct url?
<!DOCTYPE html>
<html>
<head>
<title>I have a back bone</title>
</head>
<body>
<button id="add-friend">Add Friend</button>
<button id='view-friends'>View Friends</button>
<ul id="friends-list">
</ul>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
<script>
Friend = Backbone.Model.extend({
name: null,
age: null,
});
FriendDetailModel = Backbone.Model.extend();
FriendInfoModel = Backbone.Model.extend({
name: null
});
FriendDetailCollection = Backbone.Collection.extend({
url: '../slim/index.php/people/',
model: FriendDetailModel
});
FriendInfoCollection = Backbone.Collection.extend({
model: FriendInfoModel,
url: '../slim/index.php/person/' + name,
});
Friends = Backbone.Collection.extend({
initialize: function(models, options) {
this.bind("add",options.view.addFriendLi);
}
});
AppView = Backbone.View.extend({
el: $("body"),
initialize: function() {
this.friends= new Friends(null, {view:this});
},
events: {
"click #add-friend": "showPrompt",
},
showPrompt: function () {
var friend_name = prompt("Who is your friend?");
var friend_age = prompt("What is your friends age?");
var friend_model = new Friend({name: friend_name, age: friend_age});
this.friends.add(friend_model);
},
addFriendLi: function(model) {
$("#friends-list").append("<li>" + model.get('name') + " " + model.get('age') + "</li>");
}
});
var appview = new AppView;
var people = new FriendDetailCollection;
var person = new FriendInfoCollection({name:'Sean'});
FriendView = Backbone.View.extend({
el: $("body"),
initialize: function() {
_.bindAll(this,'render');
this.collection.bind('reset', this.render);
},
events: {
"click #view-friends": "fetch_list",
},
render: function() {
var results = this.collection.toJSON();
$.each(results, function(key, value) {
var msg = results[key]['firstname'] + " " + results[key]['lastname'];
console.log(msg);
});
},
fetch_list: function() {
people.fetch({
success: function(data) {
//console.log("success");
}
});
}
});
FriendInfoView = Backbone.View.extend({
el: $("body"),
initialize: function(name) {
_.bindAll(this,'render');
this.collection.bind('reset', this.render);
},
render: function(name) {
var results = this.collection.toJSON();
$.each(results, function(key, value) {
var msg = results[key]['firstname'] + " " + results[key]['lastname'];
console.log(msg);
});
}
});
friendview = new FriendView({collection: people});
friendinfoview = new FriendInfoView({collection: person});
AppRouter = Backbone.Router.extend({
routes: {
"friends":"people",
"person/:name":"personDetail"
},
people: function() {
console.log('all the people');
people.fetch({
success: function(data) {
//console.log("success");
}
});
},
personDetail: function(name) {
person.fetch({
success: function(data) {
console.log("success");
}
});
console.log('one person named ' + name);
}
});
var approuter = new AppRouter;
Backbone.history.start();
</script>
</body>
</html>
You should define routers like this :
var AppRouter = Backbone.Router.extend({
routes: {
'name/:name' : 'getPerson'
},
getPerson: function(name) {
var callperson = new Person.Details({
name : name
});
}
Instantiate routes when dom ready
app_router = new AppRouter;
Now you can access the name like this on your view:
this.options.name
But you must define the options variable inside the initialize functions
initialize: function ( options )
And for sure you can set the model like this :
model.set('name', name)
Related
This is a betting game, made in backbone. I have a bounty of 100 to help me refactor it into a marionette based application.
I am unsure where to start - in terms of reconfiguring the models, how to swap the views out to make them regions.
I believe the steps would be to start with creating a new marionette application and router.
var app = Marionette.Application.extend({
initialize: function(options) {
console.log('My container:', options.container);
}
});
var app = new app({container: '#app'});
//router
var MyRouter = Marionette.AppRouter.extend({
appRoutes: {
"some/route": "someMethod"
},
routes : {
"some/otherRoute" : "someOtherMethod"
},
someOtherMethod : function(){
// do something here.
}
});
Then create a few regions and layouts to manage old backbone views.
//regions
MyApp.addRegions({
bankValue: "#bankvalue",
bitValue: "#bitvalue"
});
Then convert the old backbone views to Marionette's ItemViews and CompositeViews.
//compositeview
var CompositeView = Marionette.CompositeView.extend({
template: "#personalbank"
});
new CompositeView({
model: userModel,
collection: someCollection
});
Here is the latest js fiddle.
//UserBankModel
var UserBankModel = Backbone.Model.extend({
defaults: {
chips: 200
},
initialize: function() {
console.log("UserBankModel initialize");
this.on("change:chips", function(model) {
var chips = model.get("chips"); // 23232
console.log("Changed my chips to " + chips);
});
}
});
//UserBankView
var UserBankView = Backbone.View.extend({
initialize: function() {
console.log("UserBankView initialize");
this.render();
},
render: function(value) {
this.$el.html(value);
}
});
//BitcoinModel
var BitcoinModel = Backbone.Model.extend({
defaults: {
currentValue: 0,
lockedValue: 0
},
initialize: function() {
console.log("BitcoinModel initialize");
this.on("change:currentValue", function(model) {
var currentValue = model.get("currentValue"); // 494
console.log("Changed my currentValue to " + currentValue);
});
},
getBitcoinValue: function(callback) {
/*
Backbone.ajax({
dataType: 'json',
url: "https://api.bitcoinaverage.com/ticker/USD",
crossDomain: true,
success: function(data) {
callback(data);
}
});
*/
json= {
bid: 320,
ask: 444
};
var mediumValue = (json.bid + json.ask) / 2;
callback(mediumValue);
}
});
//BitcoinView
var BitcoinView = Backbone.View.extend({
initialize: function() {
console.log("BitcoinView initialize");
this.render();
},
render: function(value) {
this.$el.html(value);
}
});
var App = Backbone.Model.extend({
initialize: function() {
var that = this;
this.userBankModel = new UserBankModel();
this.userBankView = new UserBankView({
el: $("#bankvalue")
});
this.bitcoinModel = new BitcoinModel();
this.bitcoinView = new BitcoinView({
el: $("#bitvalue")
});
//setInterval(function() {
//get val of bitcoin every second
that.bitcoinModel.getBitcoinValue(function(mediumVal) {
//set bit coin model
that.bitcoinModel.set({
currentValue: mediumVal
});
//render the bit coin value
that.bitcoinView.render(that.bitcoinModel.get("currentValue"));
});
//}, 1000);
//render users chips
this.userBankView.render(this.userBankModel.get("chips"));
},
currentBitcoinValue: 0,
startBet: function(state) {
console.log("start timer");
this.state = state;
//get locked value of bitcoin for the game
var stashValue = this.bitcoinModel.get("currentValue");
//set bit coin model with locked value
this.bitcoinModel.set({
lockedValue: stashValue
});
var initialTimer = 5;
var Timer = {
i: initialTimer,
onTimer: function() {
var that = this;
document.getElementById('timer').innerHTML = Timer.i;
Timer.i--;
if (Timer.i < 0) {
app.gameResult();
Timer.i = initialTimer; //reset
} else {
setTimeout(Timer.onTimer, 1000);
}
}
};
Timer.onTimer();
},
gameResult: function() {
console.log("whats the result then");
console.log("this.state", this.state);
var lockedValue = this.bitcoinModel.get("lockedValue");
var currentValue = this.bitcoinModel.get("currentValue");
console.log("lockedValue>>", lockedValue);
console.log("currentValue>>", currentValue);
var result = "loss";//lose by default
//locked value was higher
if (
this.lockedValue > this.currentValue && this.state["bet"] == "high" ||
this.lockedValue < this.currentValue && this.state["bet"] == "low"
) {
result = "win";//win if conditions are met
}
//get current value of user chips
var newVal = this.userBankModel.get("chips");
if (result == "win") {
console.log("WIN -- you get chips");
newVal += this.state["wager"];
} else {
console.log("LOSS -- you loose chips");
newVal -= this.state["wager"];
}
//won or lost chips -- set new chip value
this.userBankModel.set({
chips: newVal
});
//render new user chips
this.userBankView.render(this.userBankModel.get("chips"));
}
});
var app = new App();
var FormView = Backbone.View.extend({
el: '#wager-form',
events: {
"submit": "doMethod"
},
doMethod: function(e) {
e.preventDefault();
var obj = [];
this.$el.find('input[name]').each(function() {
obj[this.name] = this.value;
});
//start bet
app.startBet(obj);
}
});
var form = new FormView();
I would like to know more about the best practice in using Marionette with backbone. Why use Marionette, what is the advantage?
Is it a simple case of refactoring the following example. Or does a Marionette based method work more like a collection?
var App = Backbone.Model.extend({
initialize: function() {
//standard app
}
});
But would this be the way to refactor the App model to use Marionette?
var App = Marionette.Application.extend({
initialize: function(options) {
console.log('My container:', options.container);
//invoke other models
this.otherModel1 = new OtherModel1();
this.otherView1= new OtherView1({
el: $("#selector1")
});
}
});
//add the selectors in one place?
MyApp.addRegions({
someRegion: "#some-div",
anotherRegion: "#another-div"
});
// Although applications will not do anything
// with a `container` option out-of-the-box, you
// could build an Application Class that does use
// such an option.
var app = new App({container: '#app'});
This is the structure of my application. How would I refactor it properly to use marionette
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>backbone js</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-beta1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/json2/20150503/json2.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.3/backbone-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.marionette/2.4.4/backbone.marionette.js"></script>
</head>
<body>
Content of the document......
<div id="app"></div>
<div id="select1"></div>
<div id="select2"></div>
<script>
//myModel1
var MyModel1 = Backbone.Model.extend({
initialize: function() {
console.log("myModel1 initialize");
}
});
//myView1
var MyView1 = Backbone.View.extend({
initialize: function() {
console.log("myView1 initialize");
this.render();
},
render: function(value) {
this.$el.html(value);
}
});
//myModel2
var MyModel2 = Backbone.Model.extend({
initialize: function() {
console.log("myModel2 initialize");
}
});
//myView2
var MyView2 = Backbone.View.extend({
initialize: function() {
console.log("myView2 initialize");
this.render();
},
render: function(value) {
this.$el.html(value);
}
});
//the core that invokes and bridges the other models.
var App = Backbone.Model.extend({
initialize: function() {
var that = this;
this.myModel1 = new MyModel1();
this.myView1 = new MyView1({
el: $("#select1")
});
this.myModel2 = new MyModel2();
this.myView2 = new MyView2({
el: $("#select2")
});
}
});
var app = new App();
/*ok marionette stuff*/
var MyApp = Marionette.Application.extend({
initialize: function(options) {
console.log(options.container);
}
});
var myApp = new MyApp({container: '#app'});
</script>
</body>
</html>
Ok so would the code kind of look like this? Where I pump the models into the options variable?
MyApp.addInitializer(function(options){
// do useful stuff here
var otherView1= new OtherView1({
model: options.otherModel1
});
MyApp.mainRegion.show(otherView1);
});
MyApp.addInitializer(function(options){
new MyAppRouter();
Backbone.history.start();
});
this is my current application - but I am unsure how to structure it with marionette moving forward?
Latest fiddle of the entire core application.
Ok so, I have my application with standard backbone like this..
with a core Model that invokes and bridges the other models. Something like this.
Old backbone way
var App = Backbone.Model.extend({
initialize: function() {
this.myModel1 = new MyModel1();
this.myView1 = new MyView1({
el: $("#select"),
model: this.myModel1
});
this.myModel2 = new MyModel2();
this.myView2 = new MyView2({
el: $("#select"),
model: this.myModel2
});
}
});
so is Marionette supposed to work like this?
App.addInitializer(function(options) {
App.myModel1 = new MyModel1();
App.myView1 = new MyView1({
el: $("#select1"),
model: App.myModel1
});
App.myModel2 = new MyModel2();
App.myView2 = new MyView2({
el: $("#select2"),
model: App.myModel2
});
});
and what about regions.. Do I stop using el: selectors for the view and rely on regions? And if so, how?
var View1Region = Backbone.Marionette.Region.extend({
el: "#select1", // Must be defined for this syntax
// Whatever other custom stuff you want
});
var View2Region = Backbone.Marionette.Region.extend({
el: "#select2", // Must be defined for this syntax
// Whatever other custom stuff you want
});
// Use these new Region types on App.
App.addRegions({
view1Region: View1Region,
view2Region: View2Region
});
// This is equivalent to:
App.view1Region = new View1Region();
App.view2Region = new View2Region();
I've made a new jsfiddle to start structuring the marionette version.
but am I invoking it correctly, using the new composite view correctly.
//UserBankModel
var UserBankModel = Backbone.Model.extend({
defaults: {
chips: 200
},
initialize: function() {
console.log("UserBankModel initialize");
this.on("change:chips", function(model) {
var chips = model.get("chips"); // 23232
console.log("Changed my chips to " + chips);
});
}
});
var CompositeView = Marionette.CompositeView.extend({
template: "#personalbank"
});
var userBankView = new CompositeView({
model: UserBankModel
});
var MyApp = Marionette.Application.extend({
initialize: function(options) {
console.log('My container:', options.container);
this.userBankModel = new UserBankModel();
}
});
var app = new MyApp({
container: '#app'
});
app.addRegions({
bankValue: "#bankvalue",
bitValue: "#bitvalue"
});
If we focus on the view for a second, how would I refactor this in the way I was intending to.
html
<div id="list"></div>
<script type="text/template" id="list-template">
<div class="pagination">
<ul></ul>
</div>
</script>
<script type="text/template" id="item-template">
<%= id %>
</script>
js
var Item = Backbone.Model.extend();
var Items = Backbone.Collection.extend({
model: Item
});
var Views = {};
Views.ListItem = Backbone.Marionette.ItemView.extend({
template: "#item-template",
tagName: 'li'
});
Views.List = Backbone.Marionette.CompositeView.extend({
template: "#list-template",
itemView: Views.ListItem,
itemViewContainer: "ul"
});
var Data = [
{id: 1},
{id: 2}
];
var items = new Items(Data);
var list = new Views.List({
collection: items
});
list.render();
$("#list").html(list.el);
http://jsfiddle.net/c72Vg/168/
A while ago the answer would have been "no", use Marionette's Application.addInitializer(function () {}) but when Marionette v3 is released that will be removed and in it's place you're expected to use events.
help me understand why the code is not working properly
my code:
var Link = Backbone.Model.extend({
defaults : {
groups: []
}
});
var LinkCollection = Backbone.Collection.extend({
model:Link,
url: 'item.json'
});
var Group = Backbone.Model.extend({
defaults: {
links: []
},
initialize : function() {
this.on("all" , function(event) {
console.log(event);
});
this.on("change:links" , function() {
console.log(this.get("links").length , this.id);
})
},
setLink: function(link) {
var links = this.get("links");
links.push(link);
this.set("links" , links);
this.trigger("change:links" , this);
},
removeLink : function(link) {
var links = this.get("links") , index = links.indexOf(link);
links.splice(index , 1);
this.set("links" , links);
this.trigger("change:links" , this);
}
});
var GroupCollection = Backbone.Collection.extend({
model:Group,
url: 'group.json',
setLinks : function(links) {
var self = this;
this.links = links;
this.links.on('all' , function(event) {
console.log(event);
});
this.links.on('add' , self.setLink , this);
this.links.on('remove' , this.removeLink , this);
this.links.on('reset' , this.resetLinks , this);
},
setLink : function(link) {
var self = this , test = false;
if(self.length ) {
link.get('groups').forEach(function(groupId) {
var group = self.get(groupId);
console.log(group , groupId);
if( group ) {
test = true;
group.setLink(link);
}
});
if(!test) {
self.get("notInGroup").setLink(link);
}
self.get("allObjects").setLink(link);
}
},
resetLinks : function() {
this.links.each(this.setLink);
},
initialize: function() {
var self = this;
this.on('reset' , self.resetLinks , this);
},
removeLink: function(link) {
var self = this;
link.get('groups').forEach(function(groupId) {
var group = self.get(groupId);
if(group) {
group.removeLink(link);
}
})
}
});
var LinkView = Backbone.View.extend({
tagName: 'li',
className : 'list-item',
template: _.template($("#ListView").html()),
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this
}
});
var GroupView = Backbone.View.extend({
tagName : 'li',
className: 'group-list ',
template: _.template($("#GroupView").html()),
initialize: function() {
this.model.on('remove', function() {
console.log('remove');
});
this.model.on('reset' , function() {
console.log('reset');
});
this.model.on('destroy' , function() {
console.log('destroy')
});
},
render: function() {
var model = this.model.toJSON();
this.$el.html(this.template(model));
this.renderLinks(this.model);
this.model.on('change:links' , this.renderLinks.bind(this));
return this;
},
renderLinks : function(group) {
var self = this;
self.$el.find("ul").empty();
group.get("links").forEach(function(link) {
var view = new LinkView({model: link});
self.$el.find("ul").append(view.render().el);
});
}
})
var App = Backbone.View.extend({
el: $('#content'),
initialize: function() {
this.links = new LinkCollection();
this.groups = new GroupCollection();
this.groups.setLinks(this.links);
this.groups.bind('add', this.addGroup, this);
this.groups.bind('reset', this.addGroups, this);
this.links.fetch();
this.groups.fetch({reset: true});
return this;
},
render: function() {
this.$el.html($('#GroupListView').html())
},
addGroup: function(model) {
var view = new GroupView({model: model});
this.$("ul.group-list").append(view.render().el);
},
addGroups: function() {
this.groups.each(this.addGroup)
}
})
$(function() {
var app = new App();
app.render();
})
working example http://plnkr.co/edit/40CCIq0jt2AdmGD61uAn
but instead of the expected list of groups I get incorrect group
this list i tried to get:
All Objects
First
Second
Third
Fourth
Fifth
FirstGroup
First
Third
SecondGroup
Third
Fourth
NotInGroup
Second
Fifth
upd: Groups and Links can come at different times, so the order of their receipt is not critical. the problem is that for some reason the models groups added extra value, which should not be there
Screenshot added. Please look at the highlighted change
How would I create a view and template from either this model or collection? I can console log the data I want. I'm stuck on the view and template part. Thanks.
var Weather = Backbone.Model.extend({
urlRoot: "http://api.openweathermap.org/data/2.5/weather?q=New%20York&mode=json&units=imperial",
initialize: function (response) {
console.log(response.wind.speed);
console.log(response.main.temp);
console.log(response.name);
console.log(response.main.temp_min);
console.log(response.main.temp_max);
//console.log();
return response;
}
});
var WeatherCollection = Backbone.Collection.extend({
model: Weather,
url: 'http://api.openweathermap.org/data/2.5/weather?q=New%20York&mode=json&units=imperial',
parse: function(response) {
console.log(response.wind.speed);
console.log(response.main.temp);
console.log(response.name);
console.log(response.main.temp_min);
console.log(response.main.temp_max);
//console.log();
return response;
}
});
I would probably do something like this to start with:
var WeatherItemView = Backbone.View.extend({
template: _.template($('#weather-template').html()),
render: function () {
var content = this.template({
weather: this.model
});
this.$el.html(content);
return this;
}
});
var WeatherListView = Backbone.View.extend({
initialize: function () {
this.listenTo(this.collection, 'sync', this.render);
},
render: function () {
this.collection.each(function (weather) {
var subView = new WeatherItemView({
model: weather
});
this.$el.append(subView.render().$el);
}, this);
return this;
}
});
$(document).ready(function () {
var weathers = new WeatherCollection();
weathers.fetch(); // assuming its accessing an api endpoint.
var weathersView = new WeatherListView({
collection: weathers
});
$('body').html(weathers.render().$el);
});
<!-- template for one weather item view -->
<script id='weather-template' type="text/template">
<%= weather.escape('name') %>
</script>
I have this simple BackboneJS app and it keeps returning this error on adding new model to collection: Cannot call method 'on' of undefined. Can someone help me. I can't see the problem in here.I have my templates defined in index.html, and I am using Slim framework and NotORM.
(function(){
window.App =
{
Models:{},
Collections: {},
Views : {}
}
window.template = function(id)
{
return _.template( jQuery('#' + id).html());
}
App.Models.Party = Backbone.Model.extend({
});
App.Collections.Partys = Backbone.Collection.extend({
model: App.Models.Party,
url: "http://localhost/BackboneJS/vjezba6/server/index.php/task"
});
App.Views.Party = Backbone.View.extend({
tagName :"div",
className: "box shadow aktivan",
template: template("boxovi"),
initialize: function()
{
this.model.on('change', this.render, this);
},
events:{
"click .izbrisi" : "izbrisi"
},
render: function()
{
var template = this.template( this.model.toJSON() );
this.$el.html(template);
return this;
},
izbrisi: function()
{
this.model.destroy();
},
ukloni: function()
{
this.remove();
}
});
App.Views.Partys = Backbone.View.extend({
tagName:"div",
id: "nosac-boxova",
initialize: function()
{
},
render: function() {
this.collection.each(this.addOne, this);
return this;
},
addOne: function(party) {
var partyView = new App.Views.Party({ model: party });
this.$el.append(partyView.render().el);
}
});
App.Views.Dodaj = Backbone.View.extend({
tagName: "div",
template : template("dodajTemp"),
events:
{
'submit' : 'submit'
},
submit : function(e)
{
e.preventDefault();
console.log(e);
var nazivPolje = $(e.currentTarget).find(".naziv").val();
var tekstPolje = $(e.currentTarget).find(".lokal").val();
var noviParty = new App.Views.Party({naziv:nazivPolje, tekst: tekstPolje});
this.collection.create(noviParty);
},
initialize: function()
{
},
render: function()
{
var template = this.template();
this.$el.html(template);
return this;
}
});
/* var kolekcijaPartya = new App.Collections.Partys([
{
naziv:"Ovo je prvi naziv",
tekst: "Ovo je prvi tekst"
},
{
naziv:"Ovo je drugi naziv",
tekst: "Ovo je drugi tekst"
}
]);*/
var kolekcijaPartya = new App.Collections.Partys;
kolekcijaPartya.fetch({
success: function()
{
var partysView = new App.Views.Partys({collection:kolekcijaPartya});
$("#content").prepend(partysView.render().el);
$("div.box").slideAj();
var dodajView = new App.Views.Dodaj({collection: kolekcijaPartya});
$("div#sidebar-right").html(dodajView.render().el);
}
});
})();
var noviParty = new App.Views.Party({naziv:nazivPolje, tekst: tekstPolje});
this.collection.create(noviParty);
so you are trying to add a View to your collection?
My understanding of the Backbone View is that each html element that needs to show model data can be a View by itself.
I wish to create view linked to a specific div to show model data.
My problem is that the code doesn't work if I use anything else than 'body' for el.
Following code does not work:
http://jsfiddle.net/GhaPF/9/
$(document).ready(function() {
var ToDo = Backbone.Model.extend({
defaults: { "date": "today",
"task": ""
},
initialize: function() {}
});
var ToDoList = Backbone.Collection.extend({
model: ToDo
});
var ToDoListView = Backbone.View.extend({
el: "#view1",
initialize: function(myTodoList) {
this.todolist = myTodoList;
this.todolist.bind('add', this.render, this);
},
render: function() {
text = this.todolist.toJSON();
string = JSON.stringify(text);
$(this.el).append(string);
return this;
},
events: {
"keypress #new-todo": "createOnEnter"
},
createOnEnter: function(e) {
if (e.keyCode != 13) return;
if (!$("#new-todo").val()) return;
this.todolist.add({"task": $("#new-todo").val()});
$("#new-todo").val('');
}
});
$("#new-todo").focus();
var todolist = new ToDoList();
var myToDoListView = new ToDoListView(todolist);
});
But if I use 'body' for el, it works as I want.
How can I set the el to a specific div ?
solution
http://jsfiddle.net/r3F8q/
you can also use this.setElement('#body1') in render
<div id="view-container">
<input id="new-todo" placeholder="text">
<div id="view1"></div>
<div id="view2"></div>
</div>
$(document).ready(function() {
var ToDo = Backbone.Model.extend({
defaults: { "date": "today",
"task": ""
},
initialize: function() {}
});
var ToDoList = Backbone.Collection.extend({
model: ToDo
});
var ToDoListView = Backbone.View.extend({
el: "#view-container",
initialize: function(myTodoList) {
this.todolist = myTodoList;
this.todolist.bind('add', this.render, this);
},
render: function() {
text = this.todolist.toJSON();
string = JSON.stringify(text);
this.$el.find('#view1').append(string);
return this;
},
events: {
"keypress #new-todo": "createOnEnter"
},
createOnEnter: function(e) {
if (e.keyCode != 13) return;
if (!$("#new-todo").val()) return;
this.todolist.add({"task": $("#new-todo").val()});
$("#new-todo").val('');
}
});
$("#new-todo").focus();
var todolist = new ToDoList();
var myToDoListView = new ToDoListView(todolist);
});
When you use "#view1"
"keypress #new-todo": "createOnEnter"
is not binded, because #new-todo is not within "#view1". Check API.