spine / spine

Lightweight MVC library for building JavaScript applications

Home Page:http://spine.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Binding to 'refresh' leads to duplicate triggers

dkapadia opened this issue · comments

Hi all,

I'd like to trigger a callback whenever Collection.fetch() completes fetching data from my server, but when I bind a callback to the 'refresh' event, I find that (since #486) it also gets called when a model is created.

The test case below hopefully describes the problem accurately - it relies on some setup in ajax.js.

Is 'refresh' not the correct event to be listening for in this use case, or is this a bug?

Thanks!

  it("should not trigger a collection refresh event when creating a model", function(){
    spyOn(jQuery, "ajax").andReturn(jqXHR);

    // callback is a method that we'd like to trigger 
    //  when the collection is refreshed, via User.fetch()
    var callback = jasmine.createSpy('SomeCollectionAction');
    User.bind('refresh', callback);

    User.create({first: "Hans", last: "Zimmer"});
    // However, when the response to the create request is resolved
    //  the callback above is triggered, which is not what we want.
    var newAtts = {first: "Hans", last: "Zimmer", id: "IDD"};
    jqXHR.resolve(newAtts);

    expect(callback).not.toHaveBeenCalled();
  });

seeing the same behavior when saving and existing instance of a model.
the refresh event gets called on the instance and the if you log the arguments of the trigger it passes the correct instance but the weird thing is that the bind on the classes refresh listens also on the instances refresh event.

this does not depend on ajax.coffee/ajax.js

I don't think this is a bug, but it is a problem. Refreshes should be triggering in these cases. a model is updated or created. the collection of model objects is thus changed and that in my mind equates with the refresh trigger.

The problem is that listening for the refresh event was previously described as the way to figure out if fetches had completed or some other specific model interactions. What I think we need to figure out instead is a way to consistently return promise objects when interacting with the model. For a normal ajax backed model we tend to add methods like fetchWithPromise: -> ... but having those built into spine somehow is where I think is important.

with spine 1.4+ events have been reworked some and the refresh event gets fire much less often. I don't know that that solves this problem exactly, but thinking I will close this as the real solution will be handled by some sort of overarching promise implementation in spine