I have an application which is not optimally designed. I don't have time to re-write it, and need to find a solution to the following problem:
In my application new elements may be added to the collection, and there is a function in the collection view which decides whether to insert the new element at the top or the bottom:
if (someLogic) {
this.$container.prepend( newEl );
} else {
this.$container.append( newEl );
}
There is also the possibility to edit elements; in this case the application first destroys the old view, if there is any:
item.trigger('destroyView');
and then renders it. Somehow it was rendered in the same place it was previously:
+--------+ +--------+
| x1 | | x1 |
+--------+ +--------+
| x2 | | x2 |
+--------+ ====> +--------+
| x3 | | x3a |
+--------+ +--------+
| x4 | | x4 |
+--------+ +--------+
Now, due to some changes, the edited element is rendered either at the top or at the bottom of the collection view.
My question is: how do I render it in the same place it was previously.
I tried to add a listener on the model as explained here, but some of the programmatic logic seems to be broken.
Is there any way to:
replace an existing view with a new rendered one?
OR
by iterating the container view elements, get the corresponding models? (the models have an attribute which indicates order, so I can use insertAfter
or insertBefore
)
I figured out that the solution is easier than I thought.
In the place I get the new model, I can determine whether the model exists already or not.
In case it exists, instead of destroying old view and render it again, I simply send a trigger so the view is rendered again, in the same place it was:
container view:
var model = this.collection.findWhere({id:newInteractionData.id});
if (model) {
model.trigger('render');
} else {
// here comes the old 'render' code
}
item view:
this.listenTo(this.model, "render", this.render);