There seems to be an issue with accessing Object attributes other than 'name' in the template. When trying to access attributes like id
or url
, errors such as 'id/url/whatever is not defined' are logged in the console. The JSON file passed to the view contains all items at the same level and can be accessed from the console using methods like
collectionName.models[0].get('id');
The behavior where 'name' attribute works correctly suggests that it might be predefined within backbone/underscore code as a default.
I am puzzled by this behavior. Since I am able to access model data from the console, it indicates that there could be an issue with how the view handles the data itself. Despite trying various approaches to rewrite the code, nothing seemed to resolve the problem.
Here is the relevant code:
Format of the passed object. This output is also returned when running
collectionName.models[0].attributes;
in the console.
[{
"id":"0",
"name": "Building1",
"url": "building_1",
"floors":[{
"id":"0",
"name":"Ground Floor",
"image":"",
"rooms":[{
"id": "r_1",
"name": "Room 1",
},
{
"id": "r_2",
"name": "Room 2"
}]
}
}]
}
Sample template code:
<span class="name"><%= name %></span>
<%= id %> <%= url %>
The router code:
routes: {
'': 'intro', // this route is using pretty much identical code and works fine, the model has the exact same format, the only difference is that all attributes work.
':id': 'firstLevel'
},
firstLevel: function (id) {
window.singleBuilding = new ThisBuilding({}, {idBuilding: id});
window.singleBuilding.fetch();
this.floorView = new FloorList({
collection: window.singleBuilding
});
var $intro = $('#intro');
$intro.empty();
$intro.append(this.floorView.render().el);
}
Views:
window.FloorSingleList = Backbone.View.extend({
className: 'floor-list',
initialize: function () {
this.template = _.template(tpl.get('floors-list-item'));
_.bindAll(this, 'render');
this.model.bind('change', this.render);
this.testModel = this.model.attributes;
},
render: function() {
console.log("The test data is:", this.testModel);
console.log("The actual model data is:", this.model);
var renderedContent = this.template(this.model.toJSON());
$(this.el).html(renderedContent);
return this;
}
});
window.FloorList = Backbone.View.extend({
tagName: 'section',
className: 'intro-list',
initialize: function () {
this.template = _.template(tpl.get('intro-list'));
_.bindAll(this, 'render');
this.collection.bind('reset', this.render, this);
this.collection.bind('change', this.render, this);
},
render: function(eventName) {
var $introList;
var collection = this.collection;
$(this.el).html(this.template({ }));
$introList = this.$('.intro-list');
collection.each(function(building) {
var view = new FloorSingleList({
model: building,
collection: collection
});
$introList.append(view.render().el);
});
return this;
}
});
Model code:
window.ThisBuilding = Backbone.Collection.extend({
model: Building,
initialize: function(models, options) {
// Initializing the argument passed on from the router.
this.idBuilding = options.idBuilding;
return this;
},
url: function(){
return "data.json";
},
parse: function(response) {
console.log("Passed parameters are :", this.idBuilding);
return response[this.idBuilding];
}
});
Templates & Bootstrap
// templates are loaded during the bootstrap
tpl.loadTemplates(['header', 'intro-list', 'floors-list-item', 'building-list-item'], function() {
window.App = new ExampleApp();
Backbone.history.start();
});