-
-
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
Add model changeId event #4249
Add model changeId event #4249
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this insightful fix @paulfalgout. Great to have you still on board.
Backbone does a bit of extra work to determine when to update
_byId
on every model change event becausechange:id
will not work ifidAttribute
has changed.
Just a nuance: if I'm understanding the situation correctly, the purpose of the extra work is not to support changes in the idAttribute
of individual model classes. The line that I have commented on below illustrates that Backbone does not support such a thing, and supporting it would in fact not be straightforward. Fortunately, the documentation also does not suggest that this is supported.
The real purpose of the extra work is to support polymorphic collections of multiple model types with different idAttributes. Your changes seem just as reasonable under these assumptions.
This causes issues as the
change
event happens after everychange:
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.
Brilliant. I think this is the only correct way to solve the problem. I also like the event name you've chosen; changeId
fits in comfortably with change:id
and modelId
.
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.
No, this would be an incomplete solution. Each model has only one collection
reference, but it might be a member of other collections at the same time. Those other collections would not be notified in this case.
Either of these solutions seem preferrable to handling
change:[idAttribute]
change:${idAttribute}
does not handle the polymorphic scenario, but it does handle the scenario where a model is a member of multiple collections. So I would say this solution and the previous one are about equally bad.
Replaces the need for: https://github.com/jashkenas/backbone/pull/4227/files#diff-c773bb9be277f0f3f2baa308b6e0f3a486790fe99fea81ddd0ba409846250571R1205
Yes, that's just a combination of two bad solutions.
I would like to request two refinements:
- Include the previous
id
in the event payload ofchangeId
. I suggest placing it betweenthis
andoptions
. - Add
changeId
to the Catalog of Built-in Events in the documentation.
Otherwise I'm completely convinced by your test and implementation. 🚀
@@ -1207,13 +1210,11 @@ | |||
if (model) { | |||
if ((event === 'add' || event === 'remove') && collection !== this) return; | |||
if (event === 'destroy') this.remove(model, options); | |||
if (event === 'change') { | |||
if (event === 'changeId') { | |||
var prevId = this.modelId(model.previousAttributes(), model.idAttribute); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line computes the previous id based on model
's current idAttribute
.
Ah yes, I was being lazy and using And yep, polymorphic does invalidate the other suggestion. Good catch. I'll update the PR and help in general when I can with changes. I've been lurking a bit. Great to see some movement here. |
so regarding:
I agree I missed the opportunity to align this with |
Yes that would be more consistent, but then there would be no short way to obtain the previous For what it's worth, I didn't make the remark because of consistency, but because I think event listeners might want to inspect the previous id. Initially, I even thought it might be used in |
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
61326a6
to
7712b8e
Compare
@paulfalgout I intend to make a new release. Would you consider the new |
Good question.. it's feature-y to me, but not one anyone was specifically asking for. If this is the only feature-like thing, maybe this is a patch release? |
Fixes #3882
Fixes #4159
Backbone does a bit of extra work to determine when to update
_byId
on every model change event becausechange:id
will not work ifidAttribute
has changed. This causes issues as thechange
event happens after everychange:
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