I am new to backbone and underscore and I am trying to get model index on render to do some naming inside the template. This post helps find the index on events , Backbone.js: How to get the index of a model in a Backbone Collection?
but how can I find model index on render or initialize ?
var SectionView = builder.classes.ItemView.extend({
template: _.template(
'<div class="pb-item-type-column pb-item custom-section">' +
'<div class="panel fw-row">' +
'<div class="panel-left fw-col-xs-6">' +
'<div class="column-title">Grid <%- item_index %></div>' +
'</div>' +
'<div class="panel-right fw-col-xs-6">' +
'<div class="controls">' +
'<i class="dashicons dashicons-edit edit-section-options"></i>' +
'<i class="dashicons dashicons-admin-page custom-section-clone"></i>' +
'<i class="dashicons dashicons-no custom-section-delete"></i>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="builder-items"></div>' +
'</div>'
),
events: {
'click': 'onSectionWrapperClick',
'click .edit-section-options': 'openSectionEdit',
'click .custom-section-clone': 'cloneItem',
'click .custom-section-delete': 'removeItem',
},
initialize: function() {
this.defaultInitialize();
},
render: function() {
this.defaultRender({
item_index: 'this is where I need the index'
});
},
cloneItem: function(e) {
e.stopPropagation();
var index = this.model.collection.indexOf(this.model),
attributes = this.model.toJSON(),
_items = attributes['_items'],
clonedSection;
delete attributes['_items'];
clonedSection = new Section(attributes);
this.model.collection.add(clonedSection, {
at: index + 1
});
clonedSection.get('_items').reset(_items);
},
openSectionEdit: function() {
this.modal.open();
},
removeItem: function() {
this.remove();
this.model.collection.remove(this.model);
},
});
var Section = builder.classes.Item.extend({
defaults: function() {
var defaults = _.clone(localized.defaults);
defaults.shortcode = fwThzSectionBuilder.uniqueShortcode(defaults.type + '_');
return defaults;
},
initialize: function() {
this.defaultInitialize();
/**
* get options from wp_localize_script() variable
*/
this.modalOptions = localized.options;
this.view = new SectionView({
id: 'fw-builder-item-' + this.cid,
model: this
});
},
allowIncomingType: function(type) {
if (type == 'columns') {
return true;
} else {
return false;
}
}
});
If I could ad least get the parent on render it would help me further but this does not work either
$(this.el).parent();
I am extending this https://github.com/ThemeFuse/Unyson-Builder-Extension/blob/master/includes/option-types/builder/static/js/builder.js
UPDATE AND SOLUTION :
Since this was not my app and I was extending an existing one it was very hard to find my problem. My issue was that app creator has initiated a timeout on initialize and render
thus I was early on collection search.
Morslamina answer and referenced post were both right.
So to you who is looking for index , give your index search some timeout and check. Collection must be there.
Every model that has been assigned to a collection should have an attribute this.collection
which references the parent collection. From there, it should be trivial to get the model's index.
render: function(){
index = this.model.collection.indexOf(this.model)
}
Note that this might get a bit more complicated if you've added your model to multiple collections. In that case, you'll need a reference to the specific collection that you want the index of, because Backbone won't know automagically which collection you're talking about.
EDIT: After looking more closely at your code, I think you have a scoping issue. If you are literally calling
this.defaultRender({
item_index: this.model.collection.indexOf(this.model)
});
Then this
is scoped to your object that you pass to defaultRender, not to the view.
Try instead
index = this.model.collection.indexOf(this.model)
this.defaultRender({
item_index: index
});