Reputation: 23
I have an issue using Backbone with RequireJS.
BaseListView.js
define(['backgrid',
'backbone',
'underscore', etc.], function (
Backgrid,
Backbone,
_) {
return Backbone.View.extend({
initialize: function () {
if(needDeleteCell) {
this.addDeleteCell();
}
this.render();
},
addDeleteCell: function () {
var ListViewDeleteCell = DeleteCell.extend({
defaults: {
successMsg: this.attributes.deleteSuccessMsg,
failureMsg: this.attributes.deleteFailureMsg
}
});
this.columns.push({
name: "delete",
label: "",
editable: false,
cell: ListViewDeleteCell
});
}
});
});
ChildView.js
define(['i18next', './common/BaseListView'], function (i18n, BaseListView) {
'use strict';
return BaseListView.extend({
columns: [{
name: "_id",
label: i18n.t('app.operationForm.id'),
editable: false,
cell: "string",
renderable: false
}, {
name: "name",
label: i18n.t('app.operationForm.nameLabel'),
editable: false,
cell: "string"
}]
});
});
Now if I want to use multiple instances of the child view, I have multiple "delete" columns (due to the columns.push() in the BaseListView) like if the columns
attribute of the parent is a singleton instance.
In this case, ChildView is not the only Class extending the BaseListView
What is the proper way of doing this with Bacbkone + RequireJS?
Thank you.
Edit: this is the same issue as: Switching between singleton and prototype scope using RequireJS but I'd like to avoid the factory solution.
Upvotes: 2
Views: 60
Reputation: 33344
Your ChildView.columns
is an array and is shared among the instances. You could draw inspiration from the way Backbone handles default values hashes and
columns
as a function in your ChildView
BaseListView
shadow this definition by setting a columns
attributeFor example,
var ChildView = BaseListView.extend({
columns: function() { // define `columns` as a function
return [{
name: "_id",
// ...
}, {
name: "name",
// ...
}];
}
});
and
var BaseListView = Backbone.View.extend({
initialize: function () {
this.columns = _.result(this, 'columns');
this.addDeleteCell();
},
addDeleteCell: function () {
this.columns.push({
name: "delete",
// ...
});
}
});
And a demo http://jsfiddle.net/nikoshr/9fk8axpk/1/
Upvotes: 1
Reputation: 10680
In Your case ChildView.columns is prototype scope. Every instances has the same columns
.
You may init columns
in initialize
function:
define(['i18next', './common/BaseListView'], function (i18n, BaseListView) {
'use strict';
return BaseListView.extend({
initialize: function () {
this.columns = [{
name: "_id",
label: i18n.t('app.operationForm.id'),
editable: false,
cell: "string",
renderable: false
}, {
name: "name",
label: i18n.t('app.operationForm.nameLabel'),
editable: false,
cell: "string"
}];
BaseListView.prototype.initialize.call(this);
});
}
});
Upvotes: 0