2011-01-01 11 views
9

Próbuję użyć backbone.js w mojej pierwszej "prawdziwej" aplikacji i potrzebuję pomocy w debugowaniu, dlaczego niektóre zdarzenia zmiany modelu nie są uruchamiane tak, jak bym się spodziewał.Zdarzenia zmiany modelu w kolekcjach zagnieżdżonych nie są uruchamiane zgodnie z oczekiwaniami.

Jeśli utworzę kolekcję z JSON tablicę z serwera, a następnie pobrać() w ustalonych odstępach czasu, nie otrzymam powiadomienia, jeśli zmienił się indywidualny model w kolekcji. Dokumentacja szkieletowa sugeruje, że takie powiadomienia powinny być generowane. Wszystko, co wydaje mi się otrzymywać, to powiadomienie odświeżania przy każdym pobieraniu, co nie jest użyteczne. OTOH, jeśli utworzę model z obiektu JSON obiekt z serwera, a następnie pobierz() model w określonych odstępach czasu, otrzymam powiadomienie o zmianie, gdy atrybut zostanie zmieniony. Jakieś pomysły?

Szczegóły

Mój serwis internetowy w/pracowników/{nazwa użytkownika}/zadania zwraca tablicę JSON obiektów zadaniowych, z każdego obiektu zadań gniazdowania tablicę JSON obiektów podzadania. Na przykład,

[{ 
    "id":45002, 
    "name":"Open Dining Room", 
    "subtasks":[ 
    {"id":1,"status":"YELLOW","name":"Clean all tables"}, 
    {"id":2,"status":"RED","name":"Clean main floor"}, 
    {"id":3,"status":"RED","name":"Stock condiments"}, 
    {"id":4,"status":"YELLOW","name":"Check/replenish trays"} 
    ] 
},{ 
    "id":47003, 
    "name":"Open Registers", 
    "subtasks":[ 
    {"id":1,"status":"YELLOW","name":"Turn on all terminals"}, 
    {"id":2,"status":"YELLOW","name":"Balance out cash trays"}, 
    {"id":3,"status":"YELLOW","name":"Check in promo codes"}, 
    {"id":4,"status":"YELLOW","name":"Check register promo placards"} 
    ] 
}] 

Kolejny serwis internetowy pozwala mi zmienić status określonego podzadania w określonym zadaniu, a wygląda tak:/zadania/45002/podzadań/1/status/red [bok - Zamierzam aby zmienić na usługę HTTP po bazie, ale obecna implementacja jest łatwiejszy do debugowania]

mam następujące klasy w moim app JS:

Zadanie modelu i podzadania Collection

var Subtask = Backbone.Model.extend({}); 

var SubtaskCollection = Backbone.Collection.extend({ 
    model: Subtask 
}); 

Zadanie Model z zagnieżdżonego instancji Collection podzadanie

var Task = Backbone.Model.extend({ 
    initialize: function() { 

    // each Task has a reference to a collection of Subtasks 
    this.subtasks = new SubtaskCollection(this.get("subtasks")); 

    // status of each Task is based on the status of its Subtasks 
    this.update_status(); 

    }, 
    ... 
}); 

var TaskCollection = Backbone.Collection.extend({ 
    model: Task 
}); 

Zadanie Widok, aby renderuje element i nasłuchiwania zdarzeń zmian do modelu

var TaskView = Backbone.View.extend({ 

    tagName: "li", 

    template: $("#TaskTemplate").template(), 

    initialize: function() { 
    _.bindAll(this, "on_change", "render"); 
    this.model.bind("change", this.on_change); 
    }, 

    ... 

    on_change: function(e) { 
    alert("task model changed!"); 
    } 

}); 

Po uruchomieniu programu aplikacji, Inicjuję TaskCollection (używając danych z pierwszej usługi sieciowej wymienionych powyżej), wiążę detektor zdarzeń zmian do TaskCollection i konfiguruję cykliczną setTimeout do pobrania() TaskCollecti na przykład.

... 

TASKS = new TaskCollection(); 

TASKS.url = ".../employees/" + username + "/tasks" 

TASKS.fetch({ 
    success: function() { 
    APP.renderViews(); 
    } 
}); 


TASKS.bind("change", function() { 
    alert("collection changed!"); 
    APP.renderViews(); 
}); 


// Poll every 5 seconds to keep the models up-to-date. 
setInterval(function() { 
    TASKS.fetch(); 
}, 5000); 

... 

Wszystko odbywa się zgodnie z oczekiwaniami po raz pierwszy. Ale w tym momencie oczekiwałbym jednego (lub obu) zdarzenia zmiany kolekcji lub zdarzenia zmiany modelu, aby uzyskać zwolnienie, jeśli zmienię status podzadania za pomocą mojej drugiej usługi internetowej, ale tak się nie stanie.

Zabawne, ja dostawałem Zdarzenia zmiany na ogień jeśli dodałem jeden dodatkowe poziom zagnieżdżenia z usługi internetowej powrocie jednego modelu, na przykład:

"employee":"pkaushik", "tasks":[{"id":45002,"subtasks":[{"id":1..... 

Ale to wydaje klugey ... i obawiam się, że nie zaprojektowałem mojej aplikacji poprawnie. Dodam więcej kodu, jeśli to pomoże, ale to pytanie jest już dość gadatliwe.

Myśli?

Odpowiedz

8

Słuchasz wydarzeń związanych z zadaniami, a nie z zadaniami podrzędnymi. Jeśli chcesz, aby zadanie do wykonania wydarzenia dla podzadań, a także należy zrobić coś takiego w swoim Task.initialize:

var self = this;  
this.subtasks.bind("refresh", function(){ self.trigger("refresh:subtask")}); 
this.subtasks.each(function(st){ 
    st.bind("change", function(){ self.trigger("change:subtask:" + st.id, st) }); 
}); 

może chcesz odświeżyć powiązań po zdarzeniu odświeżania również. W ten sposób, gdy wystąpi zmiana w modelu podzadań, model zadania wywoła również model zmiany.

Szkielet wysyła tylko zdarzenie odświeżania po pobraniu, dlatego nie zostaniesz poinformowany o zmianie w konkretnym modelu. Spójrz na funkcję zwrcania z kolekcji:

options.success = function(resp) { 
    collection[options.add ? 'add' : 'refresh'](collection.parse(resp), options); 
    if (success) success(collection, resp); 
}; 

on zadzwoni odświeżania domyślnie. Oto funkcja odświeżania:

refresh : function(models, options) { 
    models || (models = []); 
    options || (options = {}); 
    this.each(this._removeReference); 
    this._reset(); 
    this.add(models, {silent: true}); 
    if (!options.silent) this.trigger('refresh', this, options); 
    return this; 
} 

doda wszystkie modele do kolekcji cichu (bez zdarzeń), a następnie wywołać zdarzenie odświeżania, ale nie będzie identyfikować zmienionych elementów.

+0

Dzięki za odpowiedź! Dodałem obsługę zdarzeń zmian do każdego modelu w kolekcji, zgodnie z sugestią, ale niestety to nie pomaga. Zmienilem oryginalny post, aby lepiej opisac problem, z którym mam do czynienia (patrz druga para). Co do komentarza dotyczącego odsłuchiwania zmian w podzadaniach - nie widzę powodu, dla którego miałoby to mieć znaczenie z perspektywy zdarzenia - "podzadania" to atrybut modelu zadania, który właśnie przekształciłem w zagnieżdżoną kolekcję. Mój problem wydaje się być prostszy, niż początkowo sądziłem - po prostu nie otrzymuję powiadomień o zmianach w modelach w kolekcji. –

+0

Zaktualizowałem swoją odpowiedź. – Julien

+0

Dobre rzeczy, Julien - naprawdę cieszę się z twoich odpowiedzi na tematy związane z kręgosłupem na SO – ambertch

Powiązane problemy