Backbone Collections Undefined - backbone.js

In my database, I am simply trying to grab every object from my "countries" array, however when I run it, the console tells me that my collections is undefined.
index.js
var Backbone = require('backbone')
var App = require('./app.js')
var countryCollection = require('./collections/countries');
var countryModel = require('./models/country')
var countryView = require('./views/country-bio');
App.Views.CountryBio = new CountryBioView;
App.Router = Backbone.Router.extend({
routes: {
'bio.html(/)': 'index',
'*actions': 'defaultRoute'
},
index: function() {
console.log(countryCollection)
console.log('this works')
},
defaultRoute: function() {
console.log("404 Page Not Found")
}
})
App.Router = new App.Router;
Backbone.history.start();
Collections
var Backbone = require('backbone');
var App = require('../app');
var Country = require('../models/country');**strong text**
var CountryCollection = Backbone.Collection.extend({
url: 'http://localhost:3000/countries',
model: Country
});
App.Collections.country = new CountryCollection;
module.exports = App.Collections.country;
Models
var Backbone = require('backbone');
var App = require('../app');
App.Models.Country = Backbone.Model.extend({
url: function() {
return 'http://localhost:3000/countries';
}
});
module.exports = App.Models.Country;
Views
var $ = require('jquery');
var Backbone = require('backbone');
var countryBioTemplate = require('../templates/countryBio.hbs');
var App = require('../app');
var CountryBio = Backbone.View.extend({
el: $('main'),
collection: App.Collections.country,
render: function () {
var _this = this;
var countryCollection = this.collection;
console.log(countryCollection)
// Fetch Collection from Server
// countryCollection.fetch().done(function (country) {
// _this.$el.html(countryBioTemplate(country));
// });
}
});
module.exports = CountryBio;

Related

How to filter backbone collection to show tags

I'm creating a bookmarking tool that lets you create a list of stored bookmarks from an in-page form. The list will include an identifier tag (eg - Amazon www.amazone.com tag: shopping). From this created list, I want to also have a list showing the various tags that have been named.
This should probably use the filter method, but I cannot seem to get it to filter a correct list; I keep getting each tag listed for each URL created so there are multiple examples of the same tag.
Here is the code that correctly works in creating my form, the resulting URL list, and the module exports. This is from my Views js file:
var $ = require('jquery');
var Backbone = require('backbone');
var listTemplate = require('../../templates/addresslist.hbs');
var formTemplate = require('../../templates/addressform.hbs');
var detailTemplate = require('../../templates/addressdetail.hbs');
var AddressFormView = Backbone.View.extend({
tagName: 'form',
template: formTemplate,
events: {
'submit': 'addAddress'
},
render: function(){
var renderedHtml = this.template();
this.$el.html(renderedHtml);
return this;
},
addAddress: function(event){
event.preventDefault();
this.collection.create({
title: $('#title').val(),
url: $('#url').val(),
tag: $('#tag').val(),
});
$('#title').val('');
$('#url').val('');
$('#tag').val('');
},
});
var AddressListView = Backbone.View.extend({
tagName: 'ul',
initialize: function(){
this.listenTo(this.collection, 'add', this.renderItem);
},
render: function(){
return this;
},
renderItem: function(address){
console.log('address', address);
var addressItem = new AddressItemView({model: address});
this.$el.append(addressItem.render().el);
}
});
var AddressItemView = Backbone.View.extend({
tagName: 'li',
template: listTemplate,
render: function(){
var context = this.model.toJSON();
this.$el.html(this.template(context));
return this;
}
});
var AddressDetailView = Backbone.View.extend({
template: detailTemplate,
render: function(){
this.$el.html('').append(this.template);
return this;
}
});
module.exports = {
'AddressFormView': AddressFormView,
'AddressListView': AddressListView,
'AddressItemView': AddressItemView,
'AddressDetailView': AddressDetailView,
}
My router js file looks like this:
var $ = require('jquery');
var Backbone = require('backbone');
var views = require('./views/addressview');
var models = require('./models/address');
var Router = Backbone.Router.extend({
routes: {
'': 'index',
'detail/:id/': 'detail'
},
initialize: function(){
this.collection = new models.AddressCollection();
},
index: function(){
var addressForm = new views.AddressFormView({collection: this.collection});
$('.app').html(addressForm.render().el);
var addressListing = new views.AddressListView({collection: this.collection});
$('.app').append(addressListing.render().el);
this.collection.fetch();
},
detail: function(addressId){
this.collection.fetch().done(function(){
var address = this.collection.get(addressId);
var addressDetail = new views.AddressDetailView({model: address});
$('.app').html(addressDetail.render().el);
}.bind(this));
},
});
var router = new Router();
module.exports = router;
Create new event in view for multiple tag selection
tagSelected :function(event){
var tags = [<tag1>,<tag2>] //getting from multiple tag selection
var models = _.filter(this.collection.models,function(model){
return tags.indexOf(model.get('tag')) >= 0;
})
this.collection.reset(models);
this.render();
})

Marionette router does nothing even if backbone history is started

I work on an app with Marionette and browserify.
When I start my application, any routes is matched.
My app code :
app.js :
var App = require('./App/SaApp.js');
App.start();
SaApp.js :
var Mn = require('backbone.marionette');
var DashboardRouter = require('./modules/DashboardRouter.js');
var DashboardController = require('./modules/DashboardController.js');
var DashboardMainView = require('./modules/Dashboard/layout/DashboardMainView.js');
var Backbone = require('backbone');
var app = new Mn.Application();
app.addInitializer(function () {
console.log ('addInitializer');
var dashboardMainView = new DashboardMainView({
el: '#main-view'
});
var dashboardRouter = new DashboardRouter({
controller: new DashboardController({
mainView: dashboardMainView
})
});
dashboardMainView.render();
});
app.on("start", function(){
Backbone.history.start();
});
module.exports = app;
DashBoardRouter.js file :
var Mn = require('backbone.marionette');
var DashboardRouter = Mn.AppRouter.extend({
initialize : function () {
console.log ('router')
},
appRoutes: {
"": "indexAction",
"databases/:name":'databaseAction'
},
});
module.exports = DashboardRouter;
And DashBoardController.js :
var Mn = require('backbone.marionette');
var _ = require('underscore');
var LeftPanelView = require('./Dashboard/views/LeftPanelView.js');
var MainPanelView = require('./Dashboard/views/MainPanelView.js');
var TablePanelView = require('./TableBoard/views/TablePanelView.js');
var TableCollection = require('./Dashboard/collection/DatabaseCollection.js');
var DatabaseModel = require('./Dashboard/model/DatabaseModel.js');
var DashboardController = Mn.Controller.extend({
initialize : function(options) {
this.mainView = options.mainView;
console.log ('init')
},
indexAction : function() {
var collection = new TableCollection();
console.log ('fetch')
collection.fetch().done(_.bind(function () {
this.mainView.leftPanel.show(new LeftPanelView({
tableCollection : collection
}));
this.mainView.mainPanel.show(new MainPanelView());
}, this));
},
databaseAction : function (tableName) {
var databaseModel = new DatabaseModel();
databaseModel.urlRoot = 'databases/'+tableName;
databaseModel.fetch().done(_.bind(function() {
var tablePanelViews = new TablePanelView({
model : databaseModel
});
this.mainView.mainPanel.show(tablePanelViews);
}, this));
},
onRoute : function() {
var collection = new TableCollection();
console.log ('on route')
collection.fetch().done(_.bind(function () {
this.mainView.leftPanel.show(new LeftPanelView({
tableCollection : collection
}));
}, this));
}
});
module.exports = DashboardController;
When I start my app, all console.log are displayed in good order but indexAction is never run.
When I build code by browserify command, all is correct.
Thank you for your help.
I'm not sure, but i think you are just missing the controller (controller: myController) in the Approuter. As marionette documentation says:
var MyRouter = new Marionette.AppRouter({
controller: myController,
appRoutes: {
"foo": "doFoo",
"bar/:id": "doBar"
}
});
I know i shoudn't post links on stackoverflow, but anyway it might help you. I have done recently a basic setup with marionette and require. There you might can understand better why is not working in your case:
https://github.com/LucaMele/skeleton-marionette-require-gulp
You should find the info in the file:
https://github.com/LucaMele/skeleton-marionette-require-gulp/blob/master/modules/app.js
row 37 ( controller:new App.Router.Controller() )

Backbone remove from collection not working

var Wine = Backbone.Model.extend({
winename: "Charles Shaw"
})
var Wines = Backbone.Collection.extend({
Model: Wine
})
var divElement = Backbone.View.extend({
initialize: function () {
this.render();
},
tagName: "ul",
render: function () {
$("#div1").empty();
$("#div1").append("<ul id='ulList'></ul>"),
wines.each(function (model) {
$("#ulList").append("<li>" + model.winename + "</li>");
});
return this;
}
});
var wine1 = new Wine();
wine1.winename = "wine1";
var wines = new Wines();
wines.add(wine1);
var wine2 = new Wine();
wine2.winename = "wine2";
wines.add(wine2);
function changewinename(model, winename) {
this.winename = winename;
}
var d = new divElement(wines);
wines.on("add", addwinename);
wines.on("remove", removewinename);
function addwinename(model, winename) {
d.initialize();
}
function removewinename(model, winename) {
d.initialize();
}
function AddWine() {
var winename = $("#wineName").val();
var wineFromUI = new Wine();
wineFromUI.winename = winename;
wines.add(wineFromUI);
$("#wineName").val("");
}
function changewinename(model, winename) {
this.winename = winename;
}
function RemoveWine() {
var wineValue = $("#wineName").val();
var wine1 = new Wine();
wine1.on({ "change:winename": changewinename });
wine1.set({ winename: wineValue });
alert(wine1.winename);
wines.remove(wine1);
$("#wineName").val("");
}
Collection remove for a model isn't working. Add works fine.
you need to add a function inside your collection like this:
var Wines = Backbone.Collection.extend({
Model: Wine,
removeElement: function(elements, options) {
return this.remove(elements, options);
}
})
and call it like this in your view:
wines.removeElement(wine1);

Backbone on route not giving me the route in the callback

I am trying to call the router.on('route', callback) function, but the callback is not provided with the route ...
My router/app:
var Backbone = require('backbone')
Backbone.$ = $
var _ = require('underscore')
var App = Backbone.Router.extend({
// nothing here yet
}, {
instance: null,
getInstance: function () {
App.instance = App.instance || new App
return App.instance
}
})
module.exports = App
Some module using the router:
var IndexView = require('./views/IndexView')
var App = require('../../AppModule/js/main')
var _ = require('underscore')
var Backbone = require('backbone')
Backbone.$ = $
function IndexModule(opts) {
this.app = App.getInstance()
this.indexView = new IndexView({
view: opts.view
})
this.init = function() {
this.app.route('', _.bind(this.indexRoute, this))
this.app.route('testroute#:id', function(id) {
console.log(id)
})
this.app.on('route', _.bind(this.routeChanged, this))
}
this.indexRoute = function() {
this.indexView.render()
}
this.routeChanged = function() {
console.log(arguments)
}
}
module.exports = IndexModule
Somewhere form $(document).ready():
var indexModule = new IndexModule({
view: "someview.html"
})
indexModule.init()
Backbone.history.start({root: '/'});
If I go to testroute/2 I get this result:
["", ["2"]]
Shouldn't the route (testroute) come up in an argument as a string??
Thanks..
Just realized that you have setup the route as testroute/:id. Since id is the only variable here, only that is passed as an argument to the handler. You should try something like :routeName/:id This way, both the route name and id will be passed as arguments.

View with .fetch() not rendering

When I render this view
var MyView = Backbone.View.extend({
/* el : '.myview', used when rendered on router request */
render : function () {
var data = new Data(); /* a collection from ajax request */
var that = this;
data.fetch({
success : function (bla, data) {
var template = _.template( $('#temp').html(), {data: data.players} );
that.$el.html(template);
}
});
}
});
on router request, it works:
var Router = Backbone.Router.extend({
routes : {
'bla' : 'bla'
}
});
var myView = new MyView();
var router = new Router();
router.on('route:bla', function () {
myView.render();
});
But when I want it simply to load with the page, it doesn't:
var myView = new MyView({ el: $(".myview") });
Because in the last line you posted, you missing call to render function.
var myView = new MyView({ el: $(".myview") });
myView.render();
Besides of that, I see the workflow of initialization a bit wiered. Namely, requesting the data inside .render() function, that violates view single responsibility. Something, that I do in my applications.
var Router = Backbone.Router.extend({
routes : {
'bla' : 'bla'
},
bla: function () {
app.BlaApp();
}
});
app.BlaApp = function () {
var collection = new Collection();
collection.fetch({
success: function (collection) {
var view = new app.BlaView({model: collection});
view.render();
}
})
}
app.BlaView = Backbone.View.extend({
render: function () {
var template = // render template based on this.model;
this.$el.html(template);
return this;
}
});

Resources