Backbone.js create object from string - javascript

I want to create objects like this
var classes = {
A: <object here>,
B: <object here>,
...
};
new classes[name]()
However I cannot get it to work in my backbone app.
define([
// Application.
"app"
],
function(app) {
var Partials = app.module();
var classes = {
'AccountNavStart' : Partials.Views.AccountNavStart = Backbone.View.extend({
template: 'member/account-nav',
serialize: function(){
return { model: this.model };
}
})
};
// Required, return the module for AMD compliance.
return Partials;
});
and I try to use it like this
new Partials.classes['AccountNavStart']()
But I get an error
Uncaught TypeError: Cannot read property 'AccountNavStart' of undefined
Any ideas how to solve this problem?

Save classes to Partials before returning it:
function(app) {
//...
Partials.classes = classes;
return Partials;
});

Related

Backbone: Uncaught Type Error: .. is not a constructor

I am learning Backbone and JavaScript. I am stuck at one error and this error might be related to pure JavaScript and not Backbone.
While going through tutorial of Backbone (does not uses requireJS), I found below line of code.
var FirstSubViewModel = Backbone.View.extend({
render: function() {
var source = $("#vehicleTemplate").html();
var template = _.template(source);
this.$el.html(template(this.model.toJSON()));
this.$el.attr("data-color", this.model.get("color"));
return this;
},
});
We can clearly see that code returns this, and everything works fine.
Now I am trying to do the same in my own code base (I have used require.JS.
My view Model: With Error: Not Working
define(['backbone'], function(Backbone) {
var FirstSubViewModel = Backbone.View.extend({
template: _.template($('#myChart-template').html()),
render: function() {
$(this.el).html(this.template());
var ctx = $(this.el).find('#lineChart')[0];
return this;
},
initialize: function() {
this.render();
}
});
});
My Controller:
define(['backbone', 'FirstSubViewModel'], function(Backbone, FirstSubViewModel)
{ var ch = new dashboardModel.chart({});
new FirstSubViewModel({
^^ HERE I GET ERROR
el: '#chartAnchor1',
model: ch
});
});
My view Model: Working Totally Fine
define(['backbone'], function(Backbone) {
var FirstSubViewModel = Backbone.View.extend({
template: _.template($('#myChart-template').html()),
render: function() {
$(this.el).html(this.template());
var ctx = $(this.el).find('#lineChart')[0];
// return this; Commented Out!**
},
initialize: function() {
this.render();
}
});
return FirstSubViewModel;
});
Everything works fine if I use return FirstSubViewModel at the bottom rather than having return this in the render function . But I want to try return this in the render function and want everything to work. I don't want to do return FirstSubViewModel in the end.
Error when used "return this" in the render function:
FirstSubViewModel is not a constructor
Last return defines what will be included in other modules and in this case is required. Without this this module return undefined.
Lets try in console:
x = undefined
new x()
TypeError: x is not a constructor
return FirstSubViewModel is mandatory. return this in render function is recommended.
Code:
define(['backbone'], function (Backbone) {
var FirstSubViewModel = Backbone.View.extend({
template: _.template($('#myChart-template').html()),
render: function () {
console.log("inside first sub view render");
$(this.el).html(this.template());
var ctx = $(this.el).find('#lineChart')[0];
return this;
},
initialize: function () {
this.render();
}
});
return FirstSubViewModel; // Works as expected.
});

backbone model get throws undefined error

app.Model.Brand = Backbone.Model.extend({});
app.Collection.BrandCollection = Backbone.Collection.extend({
model: app.Model.Brand,
parse: function (response) {
return response.brandDTOList;
}
});
var brandcollection = new app.Collection.BrandCollection();
brandcollection.url = '/brands';
brandcollection.fetch({
success: function (collection, response, options) {
app.views.brandline = new app.View.BrandPanelView({
model: brandcollection
});
$('#tab-content').empty();
$('#tab-content').append(app.views.brandline.render());
}
});
In this view a single model is passed.
app.View.BrandItemPanelView = Backbone.View.extend({
initialize: function (options) {
this.views = {};
this.model.bind('destroy', this.remove, this);
},
events: {
'click .bra-edt': 'brandEditAction',
},
brandEditAction: function () {
this.model.get('image');
}
});
When i do this.model.get('image'); i get get is not a function.
I am not sure why i am getting such a error.
I tried to deep clone it but still no success. The values are there.
var newModel = new app.Model.Brand();
newModel = $.extend(true, {}, self.model);
newModel.get('image')
Your problem is where you are passing in your BrandCollection, instead of passing it in as a collection you are passing it in as a model.
So instead of
app.views.brandline = new app.View.BrandPanelView({
model: brandcollection
});
You probably want to do
app.views.brandline = new app.View.BrandPanelView({
collection: brandcollection
});
How are you instantiating the BrandItemPanelView?
You will have to pass in the model explicitly:
var view = new app.View.BrandItemPanelView({ model: myModel });
If myModel is in fact a Backbone model, it ought to have the get function...
view.model // should return your model
view.brandEditAction() // should run the function and get the 'image' attribute from your model

Ember raw JSON transform doesn't work as excepted?

I'm using the default RESTAdapter with the ActiveModelAdapter, and I want to include a JSON object in a particular model.
eg:
App.Game = DS.Model.extend(
name: attr('string')
options: attr('raw') # This should be a JSON object
)
After reading ember-data/TRANSITION.md.
I've used the same transformer from the example:
App.RawTransform = DS.Transform.extend({
deserialize: function(serialized) {
return serialized;
},
serialize: function(deserialized) {
return deserialized;
}
});
When I've tried to create an Game instance model and save it, the options attribute in the POST data was "null"(string type).
App.GamesController = Ember.ObjectController.extend(
actions:
add_new: ->
game = this.get('model')
game.set('options', {max_time: 15, max_rounds: 5})
game.save()
)
What am I missing here?
Probably you need to register your transform:
App = Ember.Application.create();
App.RawTransform = DS.Transform.extend({
deserialize: function(serialized) {
return serialized;
},
serialize: function(deserialized) {
return deserialized;
}
});
App.initializer({
name: "raw-transform",
initialize: function(container, application) {
application.register('transform:raw', App.RawTransform);
}
});
I hope it helps

backbone event listener on singleton object

I am trying to create a singleton object as a model for a view on backbone, and I want to re-render the view whenever this singleton object is being changed and updated. I am not sure the following code would be the right way of doing it or not
Model
define(function(require) {
var Singleton = require("modules/Singleton");
var Singleton = null;
var SingletonHolder = {
init: function() {
Singleton = new Singleton();
return Singleton.fetch();
},
current: function() {
return Singleton;
},
refresh: function() {
return Singleton.fetch();
}
};
return SingletonHolder;
});
Controller
var currentObj = SingletonHolder.current();
var tempView = new TempView({
model: currentObj
});
View
var TempView = Backbone.View.extend({
initialize: function() {
this.listenTo(this.model, "change", this.render);
}
render: function() {
...
}
});
For some reasons it doesn't work. Did i miss anything ? I also tried to call Singleton.refresh which it goes to the server side and fetches the latest data from the database, but it doesn't detect the changes and re-render the view.
You don't have to define a Singleton if you already use requirejs.
Singleton:
define(['models/foo'], function(FooModel){
return new FooModel;
})
Controller:
define(['foosingleton', 'tempview'], function(fooSingleton, TempView){
var tempView = new TempView({
model: fooSingleton
});
});
Here is a similar question: Is it a bad practice to use the requireJS module as a singleton?

How to load javascript files dynamically with Require.js and Backbone?

In my app, not all users will have the same modules available. So, I'd like to load the routes, based on a json I load. This works, but I can't initialize the routes in Backbone. To load the files, I use Require.js.
To get everything working i use this code:
var initialize = function () {
//TODO Authentication check
$.ajax({
url: '/auth/test#test.com/test'
});
moduleNames = new Array();
appNames = new Array();
menu = new menuCollection;
menu.fetch( {
success: function(collection) {
collection.each(function(menuitem) {
moduleNames.push('apps/' + menuitem.attributes.href + '/router');
appNames.push(menuitem.attributes.href);
});
//Here something goes wrong
require(moduleNames, function(appNames) {
//////////////////
$.each(appNames, function(i, routerName) {
console.log(routerName);
objectName = 'router' + routerName.capitalize();
console.log(objectName);
varname = routerName + '_router';
console.log(varname);
var varname = this[objectName];
console.log(varname);
});
var home_router = new routerHome;
Backbone.history.start();
});
}
});
};
A typical router file looks like:
// Filename: router.js
define([
'jquery',
'underscore',
'backbone',
'apps/profile/views/info',
'apps/profile/views/contact',
], function ($, _, Backbone, viewInfo, viewContact) {
var routerSilentbob = Backbone.Router.extend({
routes:{
// Define some URL routes
'silentbob': 'showInfo',
'silentbob/info': 'showInfo',
'silentbob/contact': 'showContact'
},
showInfo:function () {
alert('testt');
},
showContact:function () {
viewContact.render();
}
});
return routerSilentbob;
});
This is the menu object:
[{"uuid":"041e42ee-9649-44d9-8282-5113e64798cf","href":"silentbob","title":"Silent Bob"},{"uuid":"111127aa-fdfc-45e5-978f-46f1d0ea0d89","href":"menu","title":"Menu"},{"uuid":"985574e5-f7ae-4c3f-a304-414b2dc769bb","href":"youtubeengine","title":"Youtube Engine"},{"uuid":"cc84424d-9888-44ef-9895-9c5cce5a999b","href":"cardgamesdk","title":"Cardgame SDK"},{"uuid":"73f4d188-4ec5-4866-84ec-ea0fa5901786","href":"flash2flashvideo","title":"Flash2Flash videotelefonie"},{"uuid":"0702f268-116d-4d62-98e2-8ca74d7ce5f3","href":"appstore","title":"Menu"},{"uuid":"2f8606e3-b81d-43bc-a764-a0811e402c6d","href":"me","title":"Mijn profiel"},{"uuid":"bb1acae2-a6c7-404c-861c-b8a838a19614","href":"contacts","title":"Contacten"},{"uuid":"9b6e6022-fe01-40ab-b8fb-df70d31c3b28","href":"messaging","title":"Berichten"},{"uuid":"29489359-3685-4b77-9faa-6c9f63e5fe09","href":"calendar","title":"Kalender"},{"uuid":"1c9541ff-2a25-40ca-b382-3c953d440f35","href":"cubigotv","title":"Cubigo TV"},{"uuid":"5b7af683-941b-45d7-bfae-9a9e12bb09c0","href":"links","title":"Websites"},{"uuid":"27efca4c-2b64-455d-8622-367f0f13d516","href":"ideabox","title":"Idee\u00ebn"},{"uuid":"84d2c2ea-7ce7-413e-963f-7b729590b5d9","href":"companyguide","title":"Bedrijven"},{"uuid":"2a61899f-d9de-478e-a03c-64a5fd6214d7","href":"associations","title":"Verenigingen"},{"uuid":"0cf05900-cee7-4f2e-87ae-7967315c2b93","href":"myneighbourhood","title":"Mijn buurt"},{"uuid":"01ae757b-d6a3-4ab0-98cb-a741572122bf","href":"htmlwebsite","title":"HtmlWebsite"}]
So, I can't find the right way to get the objects of my routers and load them into Backbone.
Is there a way where I won't need the variable as a parameter of my function?
Or can I load it different?
Have the "router" modules return the object literal passed to Backbone.Router.Extend()
define([], function () {
return {
// Router Definition here
}
})
Then create a router module like so:
define(arrayOfModulePaths, function () {
return {
listen: function(module) {
var Router = Backbone.Router.Extend(arguments[module]);
var router = new Router();
Backbone.history.start();
}
}
})
Then you can simply require the router module and pass the module index to router.listen()
require(moduleNames, function() {
var routerObjs = {};
$.each(arguments, function(i, CustomRoute) {
var routerName = appNames[i];
routerObjs['router' + routerName.capitalize()] = CustomRoute;
});
var home_router = new routerObjs.routerHome;
Backbone.history.start();
});

Categories