Backbone.js master-detail view, navigation issue (jsfiddle included) - javascript

I'm struggling to get a simple master-detail scenario working with Backbone. Here's the jsfiddle and code is below.
Problem 1: this navigation doesn't work at all if I switch "pushstate" to true. What I really want is to have no hashes/pound signs in my urls.
Problem 2: my users might rock up on a url like /accommodation/287, not always on the home page. How would you deal with that using the router?
Thanks a lot for any help!
var AccommodationItem = Backbone.Model.extend({
defaults: {
html: "",
loaded: false
},
urlRoot: "/Home/Accommodation/"
});
var AccommodationItemView = Backbone.View.extend({
tagName: "li",
template: _.template("<a href='#accommodation/<%= id %>'><%= description %></a>"),
render: function () {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
var AccommodationList = Backbone.Collection.extend({
model: AccommodationItem
});
var DetailView = Backbone.View.extend({
initialize: function () { },
render: function () {
this.$el.html(this.model.get("html"));
},
setModel: function (model) {
this.model = model;
var $this = this;
if (!this.model.get("loaded")) {
/*
this.model.fetch({ success: function () {
$this.model.set("loaded", true);
$this.render();
}
});*/
$this.model.set("html", "<h2>Full item " + this.model.get("id") + "</h2>");
$this.model.set("loaded", true);
$this.render();
} else {
$this.render();
}
}
});
var AccommodationListView = Backbone.View.extend({
tagName: "ul",
initialize: function () {
this.collection.on("reset", this.render, this);
},
render: function () {
this.addAll();
},
addOne: function (item) {
var itemView = new AccommodationItemView({ model: item });
this.$el.append(itemView.render().el);
},
addAll: function () {
this.collection.forEach(this.addOne, this);
}
});
var App = new (Backbone.Router.extend({
routes: {
"": "index",
"accommodation/:id": "show"
},
initialize: function () {
this.detailView = new DetailView({ model: new AccommodationItem({ id: 1 }) });
$("#detail").append(this.detailView.el);
this.accommodationList = new AccommodationList();
this.accommodationListView = new AccommodationListView({ collection: this.accommodationList });
$("#app").append(this.accommodationListView.el);
},
start: function () {
Backbone.history.start({ pushState: false });
},
index: function () {
this.fetchCollections();
},
show: function (id) {
var model = this.accommodationList.get(id);
this.detailView.setModel(model);
},
fetchCollections: function () {
var items = [{ id: 1, description: "item one" }, { id: 2, description: "item two" }, { id: 3, description: "item three" }];
this.accommodationList.reset(items);
}
}));
$(function () {
App.start();
});
EDIT: In a comment below I mentioned the Codeschool backbone.js tutorial. Just want to say that I have now finished BOTH parts of the course and it DOES cover exactly the AppView pattern described in the accepted answer. It's an excellent course and I thoroughly recommend it.

you have a few of the concepts mixed up.
There is too much to explain here, so I've (very roughly) put together a patch of your code that works as you intend. I would advise that you put it side-by-side with your own and see what I have done differently.
http://jsfiddle.net/wtxK8/2
A couple of things, you should not init Backbone.history from within a router. your 'init' should look something more like this
$(function () {
window.app = new App();
window.appView = new AppView({el:document});
Backbone.history.start({ pushState: true });
});
This is setting a 'wrapper' view than encompasses the entire page. Also, you have far too much logic in your router. Try to only use the router for routes. After my quick re factor, your router only contains this:
var App = Backbone.Router.extend({
routes: {
"": "index",
"accommodation/:id": "show"
},
show: function (id) {
var model = window.appView.accommodationList.get(id);
window.appView.detailView.setModel(model);
}
});
The AppView (that I have written for you now does all of that initialize work.
var AppView = Backbone.View.extend({
initialize : function(){
this.detailView = new DetailView({ model: new AccommodationItem({ id: 1 }) });
$("#detail").append(this.detailView.el);
this.accommodationList = new AccommodationList();
this.accommodationListView = new AccommodationListView({ collection: this.accommodationList });
$("#app").append(this.accommodationListView.el);
this.fetchCollections();
},
fetchCollections: function () {
var items = [
{ id: 1, description: "item one" },
{ id: 2, description: "item two" },
{ id: 3, description: "item three" }
];
this.accommodationList.reset(items);
}
});
Even after my re factor, it's still far from optimal, but I have provided it all to help you on your journey of learning :)
I would then recommend you follow some of the on-line tutorials step-by-step so that you can set up the structure of your app in a better way.
Good Luck, and be sure to check out http://jsfiddle.net/wtxK8/2 to see it working.
EDIT: I have not address your second question. there is enough to be worked on with question 1 to keep you busy. If I have more time later, I will help further.

Related

Uncaught Type Error: View is not a constructor

I have Uncaught Type Error : UserRegisterView is not a constructor.I dont understand this error.I looked all code but i dont find it.
Sorry of my bad english.Please help me
Thanks for answer
UPDATED
UserRegisterView is here
var UserRegisterView = Backbone.View.extend({
model: User,
el: '#form',
events: {
'click input[id="infoWeek"]': 'infoWeek',
'click input[id="infoMonth"]': 'infoMonth'
},
infoWeek: function() {
this.$el.find("#dayOfMonth").hide();
this.render();
},
infoMonth: function() {
this.$el.find("#dayOfWeek").hide();
this.render();
}
});
var AddUserView = Backbone.View.extend({
el: $(".page"),
events: {
'click #saveUser': 'saveUser'
},
saveUser: function() {
var user = new User();
user.set({
username: $("#username").val(),
lastName: $("#lastName").val(),
regNumber: $("#regNumber").val(),
password: $("#password").val(),
departmentName: $("#departmentName").val(),
email: $("#email").val(),
role: $("#role").val()
});
user.save();
if (document.getElementById('isOpen').checked) {
user.set("isOpen", $("#isOpen").val("1"));
user.save();
} else {
user.set("isOpen", $("#isOpen").val("0"));
user.save();
}
if (document.getElementById('dayOfWeek').checked) {
user.set("dayOfWeek", $("#dayOfWeek").val());
user.save();
} else if (document.getElementById('dayOfMonth').checked) {
user.set("dayOfMonth", $("#dayOfMonth").val());
user.save();
}
$("#username").val("");
$("#firstName").val("");
$("#lastName").val("");
$("#regNumber").val("");
$("#password").val("");
$("#deparmentName").val("");
$("#email").val("");
$("#isOpen").val("");
$("#dayOfWeek").val("");
$("#dayOfMonth").val("");
},
render: function() {
var that = this;
var template = Handlebars.compile(UserRegister);
var myHtml = template(that.model.toJSON());
that.$el.html(myHtml);
return this;
}
});
return {
AddUserView: AddUserView,
UserRegisterView: UserRegisterView
};
});
router user func.
define([
'jquery',
'underscore',
'backbone',
'handlebars',
'spin',
'app/models/LoginModel',
'app/views/LoginView',
'app/views/UserRegisterView'
], function($,
_,
Backbone,
Handlebars,
Spinner,
Login,
LoginView,
UserRegisterView
) {
var Router = Backbone.Router.extend({
routes: {
'search': 'search',
'login': 'login',
'travels': 'travels',
'user': 'user',
'menu': 'menu',
'': 'home'
},
user: function() {
disposeView(new UserRegisterView().render());
}
dispose.view on util.js
function disposeView(view) {
Backbone.View.prototype.close = function() {
this.unbind();
this.undelegateEvents();
};
/* Şu anki viewi yok et */
if (this.currentView !== undefined) {
this.currentView.close();
}
/* Yeni view oluştur. */
this.currentView = view;
this.currentView.delegateEvents();
return this.currentView;
}
What's happening
Your UserRegisterView module returns an object which contains two constructors.
return {
AddUserView: AddUserView,
UserRegisterView: UserRegisterView
};
When using this module, what you're getting is the object above.
define([
// ...
'app/views/UserRegisterView'
], function(
// ...
UserRegisterView // value of the return in the module
) {
So you're kind of misleading yourself by calling it UserRegisterView as it's not the constructor, but the object containing the constructor.
To get a new UserRegisterView view instance with the current way your module is setup, you'd need to call it like so:
var userView = new UserRegisterView.UserRegisterView();
Or to create a AddUserView instance:
var addView = new UserRegisterView.AddUserView();
Solutions
Split up the module, one for each view constructor.
Change the name so at least it's not misleading (like UserViewsModule)
Other improvements
That being said, there are other improvements that could be made to your Backbone code.
var UserRegisterView = Backbone.View.extend({
// that's useless (if not used) and not a view property.
// model: User,
// don't use `el` like that, especially when using the view as a shared Constructor
el: '#form',
events: {
'click input[id="infoWeek"]': 'onInfoWeekClick',
'click input[id="infoMonth"]': 'onInfoMonthClick'
},
initialize: function() {
// Cache jQuery object of the view's element
this.$dayOfMonth = this.$("#dayOfMonth");
this.$dayOfMonth = this.$("#dayOfMonth");
// also use the shortcut function instead of `this.$el.find()`
}
onInfoWeekClick: function(e) {
this.$dayOfMonth.hide();
// calling render here is useless unless your using it as a parent
// view, where the child view overrides the render function.
},
onInfoMonthClick: function(e) {
this.$dayOfMonth.hide();
}
});
The disposeView function could be simplified:
function disposeView(view) {
var current = this.currentView;
if (current) current.close();
current = this.currentView = view;
current.delegateEvents();
return current;
}
Don't change the default Backbone view prototype each time the function is called. Instead, add the function once.
_.extend(Backbone.View.prototype, {
close: function() {
this.unbind();
this.undelegateEvents();
},
// any other function you want to add can go here.
});
In another answer, I go into details on how to extend Backbone's core classes with requirejs transparently.
You're already using jQuery, so don't use JavaScript DOM API document.getElementById('isOpen') interspersed with jQuery selectors $('#isOpen').
I made some improvements to the following view. Take the time to create yourself some utility functions (like reset and getValues) to simplify the flow of the code and encapsulate the complexity.
var AddUserView = Backbone.View.extend({
el: $(".page"),
events: {
'click #saveUser': 'saveUser'
},
// compile the template once while creating the view class
template: Handlebars.compile(UserRegister),
// get the selector string out of the code and place them in one place
// easy to change and maintain.
fields: {
username: "#username",
firstName: "#firstName",
lastName: "#lastName",
regNumber: "#regNumber",
password: "#password",
deparmentName: "#deparmentName",
email: "#email",
isOpen: "#isOpen",
dayOfWeek: "#dayOfWeek",
dayOfMonth: "#dayOfMonth",
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
// cache jQuery object of every field once after a render
this.field = _.reduce(this.fields, function(fields, selector, key) {
fields['$' + key] = this.$(selector);
return fields;
}, {}, this);
return this;
},
reset: function() {
// reset all the fields once without repeating code.
_.each(this.field, function($field) {
$field.val("");
});
return this;
},
getValues: function(keys) {
// get the value of multiple fields returned in a nice object
// ready to be sent to a Backbone model.
return _.reduce(keys, function(data, key) {
data[key] = this.field[key].val();
return data;
}, {}, this);
},
saveUser: function() {
var field = this.field,
user = new User(this.getValues([
'username',
'lastName',
'regNumber',
'password',
'departmentName',
'email',
'role',
]));
user.set({ isOpen: field.$isOpen.is(':checked') });
if (field.$dayOfWeek.is(':checked')) {
user.set("dayOfWeek", field.$dayOfWeek.val());
} else if (field.$dayOfMonth.is(':checked')) {
user.set("dayOfMonth", field.$dayOfMonth.val());
}
user.save();
this.reset();
},
});
In the following snippet, you're putting the context (this) into a local variable. I see that a lot and I could say that 90% of the times I see it on Stack Overflow questions, it makes no sense. It clearly screams copy-pasted.
render: function() {
var that = this;
// ...
that.$el.html(myHtml);
return this;
}
Please tell me you see that you're putting this into that, then using that throughout the function, then you still return this?!
Putting the context into a local variable is useful when the object is needed in a dynamically created callback.
render: function() {
var that = this; // this is available here
setTimeout(function() {
// here this is not available.
that.handleCallback();
}, 10);
// here we are in the same context as the first line.
return this;
}

How to reference a Backbone/Marionette View within itself?

MyView.js:
define(['app/models/MyModel'],
function (MyModel) {
return Mn.LayoutView.extend({
template: '#my-template',
className: 'my-classname',
regions: {
content: '.content-region',
panel: '.panel-region'
}
initialize: function () {
_.bindAll(this, 'childButtonClicked');
},
onShow: function () {
this.getRegion('content').show(new AnotherView());
},
childEvents: {
'some-child-click': 'childButtonClicked'
},
childButtonClicked: function (view) {
var newView = new MyView({
model: new MyModel({
title: view.model.get('title')
})
});
this.getRegion('panel').show(newView);
}
});
});
I'm trying to nest instances of MyView within itself. This worked correctly when I was building the prototype by dumping everything into one function, like so:
var MyView = Mn.LayoutView.extend({
...
childButtonClicked: function(view) {
var newView = new MyView({
...
Now that I'm trying to separate the Views into their own files and use require.js, I can't figure out the syntax for a self-referential view.
When I run this code as is, I get an error like 'MyView is undefined'.
If I add it to the require header like so:
define(['app/models/MyModel', 'app/views/MyView'],
function (MyModel, MyView) {
I get the error 'MyView is not a function'.
EDIT for solution:
The marked solution works fine, I ended up using the obvious-in-hindslght:
define(['app/models/MyModel'],
function (MyModel) {
var MyView = Mn.LayoutView.extend({
template: '#my-template',
className: 'my-classname',
regions: {
content: '.content-region',
panel: '.panel-region'
}
initialize: function () {
_.bindAll(this, 'childButtonClicked');
},
onShow: function () {
this.getRegion('content').show(new AnotherView());
},
childEvents: {
'some-child-click': 'childButtonClicked'
},
childButtonClicked: function (view) {
var newView = new MyView({
model: new MyModel({
title: view.model.get('title')
})
});
this.getRegion('panel').show(newView);
}
});
return MyView;
});
You can require() in your module: var MyView = require(app/views/MyView);.
So for want of a better place:
childButtonClicked: function (view) {
var MyView = require(app/views/MyView);
var newView = new MyView({
model: new MyModel({
title: view.model.get('title')
})
});
this.getRegion('panel').show(newView);
}

How do I get Backbone to render the subView properly?

I am relatively new to Backbone.js and having difficulty rendering a subView. I have subViews in other parts of the app working properly, but I cant even render simple text in this one.
View:
Feeduni.Views.UnifeedShow = Backbone.View.extend({
template: JST['unifeeds/show'],
tagName: "section",
className: "unifeed-show",
render: function() {
var content = this.template({ unifeed: this.model });
this.$el.html(content);
var subView;
var that = this;
this.model.stories().each(function(stories) {
subView = new Feeduni.Views.StoriesShow({ model: stories });
that.subViews.push(subView);
that.$el.find(".show-content").append(subView.render().$el);
});
return this;
},
});
Subview:
Feeduni.Views.StoriesShow = Backbone.View.extend({
template: JST['stories/show'],
tagName: "div",
className: 'stories-show',
render: function() {
this.$el.text("Nothing shows up here");
return this;
},
});
Model:
Feeduni.Models.Unifeed = Backbone.Model.extend({
urlRoot: "/api/uninews",
stories: function() {
this._stories = this._stories || new Feeduni.Subsets.StoriesSub([], {
parentCollection: Feeduni.all_unifeeds
});
return this._stories;
},
});
The text "Nothing shows up here" should be displaying in the "show content" element, but all I get is this:
<section class="unifeed-show">
<article class="show-content">
</article>
</section>
Below is a slight modification of your code showing a working main view managing some sub-views.
var UnifeedShow = Backbone.View.extend({
// I've hard-coded the template here just for a sample
template: _.template("Feed: <%= feedName %><br/> <ul class='show-content'></ul>"),
className: "unifeed-show",
initialize: function () {
// Create an array to store our sub-views
this.subViews = [];
},
render: function () {
var content = this.template(this.model.toJSON());
this.$el.html(content);
var subView;
var that = this;
var subViewContent = this.$el.find(".show-content");
this.model.stories().each(function (story) {
var subView = new StoryShow({
model: story
});
this.subViews.push(subView);
subViewContent.append(subView.render().$el);
}, this);
return this;
}
});
var StoryShow = Backbone.View.extend({
tagName: 'li',
// This template will show the title
template: _.template('Title: <%= title %>'),
className: 'stories-show',
render: function () {
var content = this.template(this.model.toJSON());
this.$el.html(content);
return this;
},
});
var Unifeed = Backbone.Model.extend({
stories: function () {
// I'm just returning the value set on this model as a collection;
// You may need to do something different.
return new Backbone.Collection(this.get('stories'));
}
});
// ================================
// Code below is creating the model & view, then rendering
// ================================
// Create our model
var feed = new Unifeed();
// Put some data in the model so we have something to show
feed.set('feedName', 'A Sample Feed');
feed.set('stories', [{
title: "Story #1",
id: 1
}, {
title: "Story #2",
id: 5
}]);
// Create our main view
var mainView = new UnifeedShow({
model: feed,
el: $('#main')
});
// Render it, which should render the sub-views
mainView.render();
Here's a working JSFiddle:
https://jsfiddle.net/pwagener/7o9k5d6j/7/
Note that while this manual sort of sub-view management works OK, you'll be better off using something like a Marionette LayoutView to help manage parent and sub-views. It builds good best practices for this sort of thing without you needing to do it yourself.
Have fun!
The subview is named Feeduni.Views.StoriesShow but in your main view you are instantiating new Feeduni.Views.StoryShow. Name them consistently and see if you still have problems.

Passing parameters to Backbone Routes to change model

I am trying to send a "point" parameter through my "discover "route, and pass it into the corresponding 'discoverPointView' function's model selector, so that I can change the model in the view based on the parameter. Can anyone explain to me how and why this isn't working? And also, you'll notice that I'm using a lot of comparative logic in the route function...can you also explain a better way to alternate between views? Thank you!
Routes:
App.Router.Main = Backbone.Router.extend({
routes: {
//DISCOVER VIGNETTE ROUTES
'discover': 'discoverView',
'discover/:point':'discoverPointView',
},
discoverView: function() {
var contentDiscover = document.getElementById('discoverWrapper');
this.hidePages();
contentDiscover.classList.add('active');
var discoverView = new AllDiscoverPointsView({collection: allDiscoverPoints});
$("#discoverWrapper").html(discoverView.render().el);
//$(".point").removeClass("active");
//$("#" + point).addClass("active");
},
discoverPointView: function(point) {
var contentDiscover = document.getElementById('discoverWrapper');
this.hidePages();
contentDiscover.classList.add('active');
var discoverView = new AllDiscoverPointsView({collection: allDiscoverPoints});
$("#discoverWrapper").html(discoverView.render().el);
if(point == "glasselephant"){
var singleDiscoverPointView = new SingleDiscoverPointView({ model: point });
$("#discoverWrapper").append(singleDiscoverPointView.render().el);
$(".subpage").removeClass("active");
$(singleDiscoverPointView.el).addClass("active");
}
if(point == "carvedstatue"){
var singleDiscoverPointView = new SingleDiscoverPointView({ model: point });
$("#discoverWrapper").append(singleDiscoverPointView.render().el);
$(".subpage").removeClass("active");
$(singleDiscoverPointView.el).addClass("active");
}
},
views:
// FULL DISCOVER POINT COLLECTION VIEW
var AllDiscoverPointsView = Backbone.View.extend({
tagName: 'ul',
render: function() {
this.collection.each(function(model) {
var discoverPointView = new DiscoverPointView({ model: model });
this.$el.append(discoverPointView.render().el);
}, this);
return this;
}
});
// SINGLE DISCOVER POINT VIEW
var DiscoverPointView = Backbone.View.extend({
tagName:'li',
className:'point',
events: {
"click": "select"
},
select: function(){
$('.point').removeClass('active');
this.$el.addClass('active');
},
template: _.template(template('discoverViewTemplate')),
render: function(){
this.id = this.model.get('idWord');
this.$el.attr('id',this.id).html(this.template(this.model.toJSON()));
return this;
}
});
// SINGLE DISCOVER POINT VIEW
var SingleDiscoverPointView = Backbone.View.extend({
tagName: 'div',
className:'subpage',
template: _.template(template('singleDiscoverViewTemplate')),
render: function(){
this.id = this.model.get('idWord');
this.$el.attr('id',this.id).html(this.template(this.model.toJSON()));
return this;
}
});
models/collections:
// COLLECTION OF ALL POINTS IN DISCOVER
var AllDiscoverPoints = Backbone.Collection.extend({
model: DiscoverPoint
});
// MODEL OF A SINGLE DISCOVER POINT
var DiscoverPoint = Backbone.Model.extend({
defaults: {
title: 'Glass Elephant',
imgPath: 'root/public/img/glass-elephant.png',
caption: 'The Imagists were extreme collectors, scouring countless thrift shops and beyond!',
link: 'discover/glasselephant',
misc: 'Any extra info goes here...'
}
});
// DISCOVER POINT MODEL INSTANCES
var glasselephant = new DiscoverPoint({
id: 1,
idWord: 'glasselephant',
title: 'Glass Elephant',
imgPath: 'root/public/img/glass-elephant.png',
caption: 'The Imagists were extreme collectors, scouring countless thrift shops and beyond!',
link: 'discover/glasselephant',
misc: 'Any extra info goes here...'
});
var carvedstatue = new DiscoverPoint({
id: 2,
idWord: 'carvedstatue',
title: 'Carved Statue',
imgPath: 'root/public/img/carved-statue.png',
caption: 'The Imagists were extreme collectors, scouring countless thrift shops and beyond!',
link: 'discover/carvedstatue',
misc: 'Any extra info goes here...'
});

Backbone JS automatically routing back to default

I've just started foundational work for a Backbone JS SPA (single page application). I'm using the basic Underscore templating support, and am having issues with unexpected routing occurring.
Basically, the sign up view is shown initially as expected, POSTs succesfully when I click a button and I have it navigate to a simple test view. However, the test view is quickly rendered and then I get re-routed to the default sign up view again.
I see the history of the test page and if I hit the back button I go back to that test view which works fine. I see there is some event being triggered in Backbone which is routing me back to the blank fragment (sign up page), but I have no idea why. I've tried messing with the replace and trigger options on the navigate call with no luck.
As a side note, the start() and stop() View functions were adapted from this article: http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/ . I tried removing this and it had no effect.
$(document).ready( function(){
Backbone.View.prototype.start = function() {
console.debug('starting');
if (this.model && this.modelEvents) {
_.each(this.modelEvents,
function(functionName, event) {
this.model.bind(event, this[functionName], this);
}, this);
}
console.debug('started');
return this;
};
Backbone.View.prototype.stop = function() {
console.debug('stopping');
if (this.model && this.modelEvents) {
_.each(this.modelEvents,
function(functionName, event) {
this.model.unbind(event, this[functionName]);
}, this);
}
console.debug('stopped');
return this;
};
var myApp = {};
myApp.SignUp = Backbone.Model.extend({
urlRoot:"rest/v1/user",
defaults: {
emailAddress: "email#me.com",
firstName: "First Name",
lastName: "Last Name",
password: "",
confirmPassword: ""
}
});
myApp.SignUpView = Backbone.View.extend({
el: $('#bodyTarget'),
modelEvents: {
'change' : 'render'
},
render: function(){
document.title = "Sign Up Page";
// Compile the template using underscore
var template = _.template( $("#signUpTemplate").html(), this.model.toJSON());
// Load the compiled HTML into the Backbone "el"
this.$el.html( template );
return this;
},
events: {
"click .signUpButton": "signUp"
},
signUp: function() {
bindFormValues(this);
this.model.save(this.model.attributes, {error: this.signUpFailure});
myApp.router.navigate("test", {trigger: true});
},
signUpFailure: function(model, response) {
alert("Failure: " + response);
}
});
myApp.TestView = Backbone.View.extend({
el: $('#bodyTarget'),
modelEvents: {
'change' : 'render'
},
render: function() {
document.title = "Test Page";
this.$el.html( "<div>this is a test view</div>");
return this;
}
});
// for now, just pull values from form back into model
function bindFormValues(view) {
var mod = view.model;
var el = view.$el;
var updates = {};
for (var prop in mod.attributes) {
var found = el.find('* [name="' + prop + '"]');
if (found.length > 0) {
updates[prop] = found.val();
}
}
mod.set(updates/*, {error: errorHandler}*/);
}
// routers
myApp.Router = Backbone.Router.extend({
routes: {
'test': 'test',
'': 'home',
},
home: function() {
console.debug('home:enter');
this.signUpView = new myApp.SignUpView({model: new myApp.SignUp()});
this.showView(this.signUpView);
console.debug('home:exit');
},
test: function() {
console.debug('test:enter');
this.testView = new myApp.TestView({model: new myApp.SignUp()});
this.showView(this.testView);
console.debug('test:exit');
},
showView: function(view) {
if (this.currentView) {
this.currentView.stop();
}
this.currentView = view.start().render();
}
});
myApp.router = new myApp.Router();
Backbone.history.start();
});
My HTML page just brings in the relevant scripts and has the div element bodyTarget which is injected with the views when it loads.
Edit: Duh, I found the problem. It turns out I needed to prevent event propagation on the call to signUp() by returning false.

Categories

Resources