backbone.layoutmanager and handlebars template engine - backbone.js

I'm using the backbone.layoutmanager project:
https://github.com/tbranyen/backbone.layoutmanager#readme
can some one please post a sample with handlebars template engine?
containing the modified app.js file and an instance view?
i have followed the instructions and i'm a bit confused what should i do in the instance level and the global.
i keep getting the "has no method 'match' err message on my template.
Thanks

Your modified app.js will work with something like this:
define([
"jquery",
"underscore",
"backbone",
"handlebars",
"plugins/backbone.layoutmanager"
],
function($, _, Backbone, Handlebars) {
"use strict";
var JST = window.JST = window.JST || {};
Backbone.LayoutManager.configure({
paths: {
layout: "path/to/layouts/",
template: "path/to/templates/"
},
fetch: function(path) {
path = path + ".html";
if(!JST[path]) {
$.ajax({ url: "/" + path, async: false }).then(function(contents) {
JST[path] = Handlebars.compile(contents);
});
}
return JST[path];
}
// It is not necessary to override render() here.
});
var app = {
// Define global resources here.
};
return _.extend(app, Backbone.Events);
});
An example of a view:
var SampleView = Backbone.View.extend({
template: "path/to/sample/template",
// Override this for fine grained control of the context used by the template.
serialize: function() {
return {
property: 1,
anotherProperty: 2
};
}
// No need to override render() for simple templates.
});
And the template associated with the view:
<div>
<h2>{{property}}</h2>
<h2>{{anotherProperty}}</h2>
</div>

Related

Uncaught TypeError: Cannot read property 'navigate' of undefined

So I developed a simple CRUD program from the tutorial video of backbonejs.org and the code worked fine. Now I'm trying to implement the code in requirejs but it shows following error in the following code: -
define([
'jquery',
'underscore',
'backbone',
'router',
'models/Customers/Customer',
'helper/Serialize'
], function ($, _, Backbone, Router, Customer, Serialize) {
var CustomerEditView = Backbone.View.extend({
el: '.page',
events: {
'submit .edit-customer-form': 'saveCustomer',
'click .delete': 'deleteCustomer',
},
saveCustomer: function (ev) {
var customerDetails = $(ev.currentTarget).serializeObject();
var customer = new Customer();
customer.save(customerDetails, {
success: function (customer) {
this.router.navigate('', { trigger: true });
}
});
return false;
},
You can use :
customer.save(customerDetails, {
success: function (customer) {
Backbone.history.navigate('', { trigger: true });
}
if you want to use router object first you have to initialize it like
this.router = new router();
and you can say this.router.navigate('', { trigger: true });
it is not optimal to create a new instance in all the views and not suggested to make the object global. You can use Backbone.history.nvaigate which is alias to router.nvaigate

Backbone: My model doesn't pass the id. Its a commenting system. I am trying to post the created comment, to the backend

Backbone:I'm trying to create a commenting system. My model doesn't pass the id. I am trying to post the created comment, to the backend.
When trying to create, passing id value as option, but it never gets passed to the options in collection.
Part of the code, is as below:
this.collection.create({body: commentVal},({wait: true,id : _id}));
/* This is comments Model */
define([
'backbone'
], function(Backbone){
var CommentModel = Backbone.Model.extend({
defaults: {
body: " "
}
});
//Returns the model for the module
return CommentModel;
});
/* This is comments collection */
define([
'jquery',
'backbone',
'../models/comment'
], function($, Backbone, CommentModel){
var CommentCollection = Backbone.Collection.extend({
model: CommentModel,
url: function() {
var urlRoot = '/api/v1/comment';
return urlRoot + '/' + this.id;
},
initialize: function(attrs,options){
this.id = options.id;
}
});
return CommentCollection; // We should never return collection instantiated.
});
This way should work for you:
var comments = new CommentCollection([],{id:_id });
comments.fetch({
success: function(){},
error: function(){}
});

backbone.js Uncaught TypeError: Cannot read property 'View' of null

When I run my backbone app in NetBeans 7.3.1, the main page displays for a few seconds, maybe 5 or 6, then in NetBeans output I see the following...
Uncaught TypeError: Cannot read property 'View' of null (18:43:36:307 | error, javascript)
at (js/views/HomeView.js:6:28)
at d.execCb (js/libs/require/require.js:27:197)
at o (js/libs/require/require.js:10:471)
at (js/libs/require/require.js:12:184)
at o (js/libs/require/require.js:12:75)
at (js/libs/require/require.js:14:1)
at o (js/libs/require/require.js:12:75)
at l (js/libs/require/require.js:12:336)
at g.finishLoad (js/text.js:10:192)
at g.load (js/text.js:10:354)
at window.undefined.window.navigator.window.document.c.onreadystatechange (js/text.js:7:30)
Uncaught TypeError: Cannot read property 'Model' of null (18:43:36:317 | error, javascript)
at (js/models/Member.js:6:26)
at d.execCb (js/libs/require/require.js:27:197)
at o (js/libs/require/require.js:10:471)
at x (js/libs/require/require.js:15:186)
at m (js/libs/require/require.js:15:207)
at g.completeLoad (js/libs/require/require.js:21:388)
at d.onScriptLoad (js/libs/require/require.js:27:490)
Uncaught Error: Load timeout for modules: text!templates/homeTemplate.html
http://requirejs.org/docs/errors.html#timeout (18:43:38:511 | error, javascript)
at N (js/libs/require/require.js:7:217)
at A (js/libs/require/require.js:16:230)
at (js/libs/require/require.js:16:394)
It looks like RequireJS is failing to load Backbone. Here is main.js...
// Filename: main.js
require.config({
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
}
},
paths: {
jquery: 'libs/jquery/jquery-min',
underscore: 'libs/underscore/underscore-min',
backbone: 'libs/backbone/backbone-min',
templates: '../templates'
}
});
require([
'app',
], function(App) {
App.initialize();
});
I'm totally spinning my wheels on this. Why is Require not loading Backbone?
#Sushanth--: Edited original post to include HomeView.js
Here is the HomeView.js...
define([
'jquery',
'underscore',
'backbone',
'text!templates/homeTemplate.html'
], function($, _, Backbone, homeTemplate) {
var HomeView = Backbone.View.extend({
el: $("#page"),
initialize: function() {
},
render: function() {
var compiledTemplate = _.template( homeTemplate, {} );
this.$el.html( compiledTemplate );
}
});
return HomeView;
});
#Sushanth--: I'm rendering from the router.js...
// Filename: /js/router.js
define([
'jquery',
'underscore',
'backbone',
'views/HomeView',
'views/MembersView'
], function($, _, Backbone, HomeView, MembersView) {
var AppRouter = Backbone.Router.extend({
routes: {
// Define some URL routes
'members': 'showMembers',
// Default
'*actions': 'defaultAction'
}
});
var initialize = function(){
//alert('router init');
var app_router = new AppRouter;
app_router.on('route:showMembers', function () {
// Like above, call render but know that this view has nested sub views which
// handle loading and displaying data from the GitHub API
var membersView = new MembersView();
});
app_router.on('route:defaultAction', function (actions) {
// We have no matching route, lets display the home page
var homeView = new HomeView();
homeView.render();
});
// Unlike the above, we don't call render on this view as it will handle
// the render call internally after it loads data. Further more we load it
// outside of an on-route function to have it loaded no matter which page is
// loaded initially.
//var footerView = new FooterView();
//alert('hello from router.js');
//Backbone.history.start({pushState: true, root: "/modular-backbone/"});
//Backbone.history.start({pushState: true});
Backbone.history.start();
};
return {
initialize: initialize
};
});
Added a test alert in main.js, app.initialize...
require(['app'], function(App) {
// THIS ALERT NEVER DISPLAYS!?!?!
alert('inside main.js before app.initialize');
App.initialize();
});
I replaced my Backbone and Underscore js files with the AMD versions and it started working.

uncaught typeerror: object function has no method 'tojson'

I have created a model like this
define(['backbone', 'text_dictionary'], function(Backbone, Text_Dict) {
var IndexPageModel = Backbone.Model.extend({
defaults:{
val_btn_gotohomepage : Text_Dict.val_btn_gotohomepage,
val_btn_gotologinpage : Text_Dict.val_btn_gotologinpage,
val_btn_gotolistpage : Text_Dict.val_btn_gotolistpage
}
});
return IndexPageModel;
});
and instantiated this model with 'new' in my page code like this
define([ 'page_layout',
'panel_itemview',
'header_itemview',
'content_itemview',
'footer_itemview',
'templates',
'text_dictionary',
'indexpage_model',
'indexpage_logic'],
function( Page,
Panel,
Header,
Content,
Footer,
Templates,
Text_Dict,
IndexPageModel,
IndexPage_BusnLogic) {
console.log("Success..Inside Index Page.");
var Page_Index = {};
Page_Index.page = (function(){
var _pageName = Text_Dict.indexpage_name;
var _pageModel = new IndexPageModel();
return _pageLayout = Page.pageLayout({
name:_pageName,
panelView: Panel.panelView({name:_pageName, pagetemplate: Templates.simple_panel}),
headerView: Header.headerView({name:_pageName, title: Text_Dict.indexpage_header, pagetemplate: Templates.header_with_buttons}),
contentView: Content.contentView({name:_pageName, page_model:_pageModel, pagetemplate:Templates.content_index, busn_logic:IndexPage_BusnLogic.HandleEvents}),
footerView: Footer.footerView({name:_pageName, title: Text_Dict.indexpage_footer, pagetemplate: Templates.simple_footer})
});
})();
return Page_Index;
});
my page gets created using the page layout
define([ 'underscore', 'marionette' ], function( _, Marionette ) {
console.log("Success..Inside Index View.");
var Page = {};
var _ReplaceWithRegion = Marionette.Region.extend({
open: function(view){
//Need this to keep Panel/Header/Content/Footer at the same level for panel to work properly
this.$el.replaceWith(view.el);
}
});
Page.pageLayout = function (opts) {
var _opts = _.extend ({ name: 'noname',
panelView: null,
headerView: null,
contentView: null,
footerView: null,
}, opts);
return new ( Marionette.Layout.extend({
tagName: 'section',
attributes: function() {
return {
'id': 'page_' + _opts.name,
'data-url': 'page_' + _opts.name,
'data-role': 'page',
'data-theme': 'a'
};
},
template: function () {
return "<div region_id='panel'/><div region_id='header'/><div region_id='content'/><div region_id='footer'/>";
},
regions: {
panel: {selector: "[region_id=panel]", regionType: _ReplaceWithRegion},
header: {selector: "[region_id=header]", regionType: _ReplaceWithRegion},
content: {selector: "[region_id=content]", regionType: _ReplaceWithRegion},
footer: {selector: "[region_id=footer]", regionType: _ReplaceWithRegion},
},
initialize: function(){
$('body').append(this.$el);
this.render();
},
onRender: function() {
if (this.options.panelView) {
this.panel.show (this.options.panelView);
};
if (this.options.headerView) {
this.header.show (this.options.headerView);
};
if (this.options.contentView) {
this.content.show(this.options.contentView);
};
if (this.options.footerView) {
this.footer.show (this.options.footerView);
};
},
}))(_opts);
};
return Page;
});
but in my itemview when i am passing model reference like this
define([ 'underscore', 'marionette', 'event_dictionary', 'app' ], function(_,
Marionette, Event_Dict, App) {
console.log("Success..Inside Content Index View.");
var Content = {};
Content.contentView = function(opts) {
return new (Marionette.ItemView.extend({
tagName : 'div',
attributes : function() {
console.log('options name==' + opts.name);
console.log("page model=="+opts.page_model);
return {
'region_id' : 'content',
'id' : 'content_' + opts.name,
'data-role' : 'content'
};
},
initialize : function() {
_.bindAll(this, "template");
},
template : function() {
return opts.pagetemplate;
},
model : function() {
return opts.page_model;
}
}))(opts);
};
return Content;
});
It's giving me error
Uncaught TypeError: Object function () {
return opts.page_model;
} has no method 'toJSON'
The model property of a view cannot be a function. Backbone allows this for some things like url (by way of the _.result helper function), but not in this case. Change your view code to not have a model function and just do this in initialize:
initialize: function (options) {
this.model = this.page_model = options.page_model;
}
UPDATE since you won't just take my word for it, here is the Marionette source that is almost certainly the top of your exception stack trace. Once again: view.model has to be a model object not a function. Fix that and the error will go away.
The accepted answer is correct, but it took a bit of messing about to find out why I had that error coming up, so I'm offering what the solution for my personal use-case was in case it helps anyone else stumbling upon this page in the future.
I had this:
app.module 'Widget.Meta', (Meta, app, Backbone, Marionette, $, _) ->
Meta.metaView = Backbone.Marionette.ItemView.extend
model: app.Entities.Models.meta
template: '#meta-template'
... when I should have had this:
app.module 'Widget.Meta', (Meta, app, Backbone, Marionette, $, _) ->
Meta.metaView = Backbone.Marionette.ItemView.extend
model: new app.Entities.Models.meta()
template: '#meta-template'
It's just a matter of instantiating the function definition.

After integrating requirejs in backbone app, (view) not working

I am developing my backbone application using require.js. all were fine. up to I integrate the routers. after I integrate my router I'm getting errors saying:
TypeError: appView is undefined
[Break On This Error]
that.$el.append(new appView.getView({model:data}).render());
and in the view.js I'm unable to route using this line(i intentionally commented)
listTrigger:function(){
myApp.navigate("/student");
}
and i post my all codes here... anyone can suggest or correct my code. or give me the reasons what i am doing wrong here?
main.js
require.config({
baseUrl: 'js/',
paths:{
'jquery' :"lib/jquery.min",
'underscore' :"lib/underscore-min",
'backbone' :"lib/backbone-min",
'appModel' :"app/model/model",
'appView' :"app/views/view",
'appViews' :"app/views/views",
'appRoute' :"app/router/router"
},
shim:{
underscore:{
exports:"_"
},
backbone:{
exports:"Backbone",
deps:["jquery","underscore"]
}
}
});
require(["appRoute"], function(appRoute) {
var myApp = new appRoute.getRoute();
Backbone.history.start();
});
model.js
define("appModel", ['backbone'], function(Backbone){
"use strict"
var appModel = Backbone.Model.extend({});
var appCollection = Backbone.Collection.extend({
model:appModel,
initialize:function(){
// console.log("initialized from collection");
}
});
return {
model: appModel,
collect:appCollection
}
});
view.js
define("appView", ["backbone","appViews"], function(Backbone,appViews){
"use strict"
var appView = Backbone.View.extend({
tagName:"li",
template:_.template($("#listTemp").html()),
events:{
"click" : "listTrigger"
},
initialize:function(){
this.render();
},
render:function(){
return this.$el.html(this.template(this.model.toJSON()));
},
listTrigger:function(){
// myApp.navigate("/student");
}
});
return{
getView: appView
}
})
views.js with some json data:
define('appViews', ["backbone","appModel","appView"], function(Backbone,appModel,appView){
"use strict";
var students = [
{"name":"student1"},{"name":"student2"},
{"name":"student3"},{"name":"student4"},
{"name":"student5"},{"name":"student6"},
{"name":"student6"},{"name":"student8"},
{"name":"student9"},{"name":"student0"}]
var appViews = Backbone.View.extend({
el:$("#app").find('ul'),
initialize:function(){
this.collection = new appModel.collect(students);
this.collection.on('reset', this.renderAll);
this.renderAll();
},
render:function(){
console.log("render called from views");
},
renderOne:function(){
console.log("render one")
},
renderAll:function(){
var that = this;
this.collection.each(function(data,i){
that.$el.append(new appView.getView({model:data}).render());
})
}
});
return {
appViews : appViews
}
})
router.js
define('appRoute', ["backbone","appModel","appView","appViews"], function(Backbone,appModel,appView,appViews){
var appRouter = Backbone.Router.extend({
routes:{
"":"initiate"
},
initialize:function(){
// console.log("called from routersssss");
},
initiate:function(){
new appViews.appViews();
}
})
return {
getRoute : appRouter
}
})
across this all are working correct up to using routers. after I'm not getting the result. Am I using routers incorrectly?
#TomasKirda: you can new-up without the trailing parentheses, but I wouldn't recommend it! Also, see here.
Having said that, you have identified the problem in this instance!
This code:
new appView.getView(...);
Is trying to create a new appView.getView which isn't a reference to a constructor (it would be if the appView constructor had a property getView).
So in this case, you are quite right that the parentheses are required:
new appView().getView(...);

Resources