spine / spine

Lightweight MVC library for building JavaScript applications
http://spine.github.io
MIT License
3.66k stars 426 forks source link

Triggering refresh on model instance no longer triggers refresh on the model class #585

Closed richard-flosi closed 9 years ago

richard-flosi commented 9 years ago

In Spine 1.3.2 triggering refresh on a model instance would also trigger refresh on the model class:

// Version 1.3.2
  trigger: (args...) ->
    args.splice(1, 0, this)
    @constructor.trigger(args...)

In Spine 1.4.1 triggering refresh on a model instance explicitly does NOT trigger refresh on the model class for an unknown reason:

// Version 1.4.1
  trigger: ->
    Events.trigger.apply this, arguments # fire off the instance event
    return true if arguments[0] is 'refresh' # Don't trigger refresh events, because ... ?
    @constructor.trigger arguments... # fire off the class event

https://github.com/spine/spine/blob/dev/src/spine.coffee#L489

I'd like to know why this changed. I don't see a reason for it to have changed. This change is also breaking my app developed against Spine 1.3.2.

adambiggs commented 9 years ago

Just commented on that commit, but then saw you opened this issue.

That line is there to stop each instance from triggering a class event when the model is updated with multiple records (could easily become 1000s of class events for a single model refresh).

But I didn't consider how this would break cases of manually triggering instance events...

Open to suggestions on how this could be improved, but in the meantime you could manually trigger the class event as a workaround. Something like record.constructor.trigger 'refresh', [record].

richard-flosi commented 9 years ago

Do you have an example of where the previous functionality is a problem?

It seems unlikely, though not impossible, to update 1,000s of model instances at once.

For that scenario I would imagine you have a list of 1,000 items with checkboxes and a save button at the end of the form. Do you have a better example?

Thanks!

adambiggs commented 9 years ago

Do you have a better example?

SomeModel.fetch()

Fetching a model refreshes that model with the JSON from the ajax response. Without the line in question, you'd get a class refresh event for every record in the response.

This change happened in #558.

aeischeid commented 9 years ago

Yes, the superfluous refresh events on fetch always annoyed me. So I would like to continue keeping that a little cleaner on the one hand, but on the other I can see why having it is good. Some methods have a option that can be set to not fire triggers... maybe we could look into something like that.

aeischeid commented 9 years ago

also may relate to #503. which might be resolved now that I think about it...

richard-flosi commented 9 years ago

Seems reasonable. Perhaps the comment should be updated. :) @adambiggs I'm trying out your suggestion using constructor.trigger which seems to be working so far.

richard-flosi commented 9 years ago

I think instead of using constructor.trigger, I can just listen for the change event on the class in this case. It looks like change is triggered by the instance refresh. Can I expect that to be stable?

richard-flosi commented 9 years ago

actually, i don't think i'm going to listen to the change event, though I think that would be a quick fix for anyone wanting to upgrade. I'm going to refactor my code and either trigger refresh on the class, or more likely just call the method I need directly.

I'm closing this out as I don't think there is any action to take here. Thanks!

adambiggs commented 9 years ago

@richard-flosi that's right, change is now triggered when the model is refreshed. The idea I had was that change should be triggered whenever anything in the model changes, so it's a good event to use for stuff like this.