2012-04-01 4 views
0

У меня есть коллекция Backbone. Я использую fetch для ленивой загрузки сообщений Facebook в модель при инициализации.Перед отправкой передано в фоновый режим Fetch, не позволяя запускать события

https://gist.github.com/2271437

exports.Collection = class Posts extends Backbone.Collection 
    initialize: (models, options) => 
    @id = options.id 
    @activeDetails = false 
    @on "loadDetails", @loadDetails 
    @on "detailsLoaded", @logger 
    debug "initialized posts" 
    @fetch 
     beforeSend:() => 
     console.log "about to fetch..." 
     @trigger "postsLoading" 
     success: (collection, response) => 
     debug "successfully loaded ajax" 
     @trigger "postsLoaded" 
     error: (collection, response) => @trigger "postsLoadingError" 

По какой-то странной причине, когда я пытаюсь вызвать события, используя beforeSend обработчик события не вызывают. Я могу вызывать любые функции, но если какие-либо функции пытаются использовать @trigger "eventName", событие никогда не срабатывает так, как я мог наблюдать. В приведенном выше примере функция console.log работает нормально, но сбой триггера.

Любые идеи? Успешные и обработчики ошибок работают великолепно.

ответ

2

Вы вызываете fetch в свой метод initialize, поэтому ничто не будет иметь возможности привязываться к этой коллекции до того, как будут запущены события. Метод initialize вызывается, пока создается экземпляр вашей коллекции, а это означает, что вы вызываете fetch до того, как конструктор вернется, но вам нужен экземпляр коллекции, прежде чем вы сможете привязываться к ее событиям.

Рассмотрим то, что выглядит примерно так:

class Posts extends Backbone.Collection 
    do_things: -> 
    @fetch 
     beforeSend:() => 
     console.log "about to fetch..." 
     @trigger "postsLoading" 
     success: (collection, response) => 
     debug "successfully loaded ajax" 
     @trigger "postsLoaded" 
     error: (collection, response) => @trigger "postsLoadingError" 

Тогда, если вы сделаете это:

p = new Posts 
p.on('postsLoading', -> console.log('loading'))  
p.do_things() 

вы увидите, что ваш postsLoading событие действительно срабатывает.

Демо: http://jsfiddle.net/ambiguous/PDeFg/

Мораль этой истории проста:

Не называйте fetch внутри конструктора, если вы заботитесь о обработчиках событий.

+0

Я ЛЮБЛЮ ТЕБЯ. Мог ли я установитьTimeout другую функцию в объекте, чтобы ждать галочку перед извлечением и все еще иметь преимущества выборки, когда объект инициализируется? – RandallB

+0

@RandallB: старый 'setTimeout (..., 0)' трюк внутри 'initialize' должен работать до тех пор, пока вызывающий объект связывает свои обработчики событий сразу после создания экземпляра коллекции (и вы, вероятно, захотите документировать это поведение). –