-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Internal _byId index of Collections wrong during model change event #3882
Comments
Why not just use the model passed to the listener? This is almost impossible to fix, because updating the var Collection = Backbone.Collection.extend( {
model: Entry,
initialize() {
this.on('change', (model) => {
console.log('onChange Collection', model.id, model, model);
});
}
}); |
I see your point, but sometimes, as in my case, it's not possible to use the model passed to the listener. On the high level, I think that the way collection's internal indexing is done should be transparent to the user - whether I know this may be hard to fix with the current implementation, but maybe some warning about this quirk in the docs would help others who may fall into this? On why it's not always possible to use the model passed to the listener (long read): |
We essentially have this due to #2602, which landed in v1.1.0. |
Fixes #3882 Fixes #4159 Backbone does a bit of extra work to determine when to update `_byId` on every model change event because `change:id` will not work if `idAttribute` has changed. This causes issues as the `change` event happens after every `change:` event which means during a change the `_byId` hasn't updated. Rather than adding complexity to collection the solution is to have the model notify with the id changes. If adding a public event isn't desired, for an internal solution the model is aware of it's collection and could modify model.collection._byId directly within the set. Either of these solutions seem preferrable to handling `change:[idAttribute]` Replaces the need for: https://github.com/jashkenas/backbone/pull/4227/files#diff-c773bb9be277f0f3f2baa308b6e0f3a486790fe99fea81ddd0ba409846250571R1205
Fixes #3882 Fixes #4159 Backbone does a bit of extra work to determine when to update `_byId` on every model change event because `change:id` will not work if `idAttribute` has changed. This causes issues as the `change` event happens after every `change:` event which means during a change the `_byId` hasn't updated. Rather than adding complexity to collection the solution is to have the model notify with the id changes. If adding a public event isn't desired, for an internal solution the model is aware of it's collection and could modify model.collection._byId directly within the set. Either of these solutions seem preferrable to handling `change:[idAttribute]` Replaces the need for: https://github.com/jashkenas/backbone/pull/4227/files#diff-c773bb9be277f0f3f2baa308b6e0f3a486790fe99fea81ddd0ba409846250571R1205
During model change event, when
id
attribute changes, the internal_byId
index of containing collection is invalid. Because of this, the model cannot be obtained withcollection.get(id)
method, even though it has ID attribute already set. This is non-intuitive as internal indexing of collections should be transparent to the end user, and whencollection.get(ID)
returns null, it should be be safe to assume that the model with such ID does not exist in collection.Internally, this issue is caused by delayed firing of collection's
_onModelEvent
method which maintains thebyId
index (backbone/backbone.js
Line 1144 in 05fde9e
all
event on model level, andall
handlers are invoked only after all other events are processed (backbone/backbone.js
Line 357 in 05fde9e
Please see the example below:
It's console output is:
Please note that in the model change handler the collection is in invalid state, as
collection.get(10)
producedundefined
whilecollection.get('c1').id
returns 10, meaning that the object with ID 10 is actually in the collection.Also, the second line shows inconsistency with the
change
event bound at the collection level, which behaves correctly.The text was updated successfully, but these errors were encountered: