Modelländerungsereignisse in verschachtelten Sammlungen, die nicht wie erwartet schießen

StackOverflow https://stackoverflow.com/questions/4576150

  •  14-10-2019
  •  | 
  •  

Frage

Ich versuche, Backbone.js in meiner ersten "echten" Anwendung zu verwenden, und ich brauche Hilfe, um zu debuggen, warum bestimmte Modellwechsel -Ereignisse nicht wie ich erwarten würde.

Wenn ich eine Sammlung von einem JSON erstelle Array Auf dem Server, dann fetch () in festgelegten Intervallen, werde ich nicht benachrichtigt, wenn sich ein einzelnes Modell in der Sammlung geändert hat. Die Backbone -Dokumentation legt nahe, dass solche Benachrichtigungen generiert werden sollten. Alles, was ich zu bekommen scheine, ist eine Aktualisierungsbenachrichtigung bei jedem Abruf, was nicht nützlich ist. OTOH, wenn ich ein Modell von einem JSON erstelle Objekt Auf dem Server, dann fetch () das Modell in festgelegten Intervallen, erhalte ich eine Änderungsbenachrichtigung, wenn sich ein Attribut ändert. Irgendwelche Ideen?

Einzelheiten

Mein Webservice at/Mitarbeiter/{Benutzername}/Tasks gibt ein JSON -Array von Aufgabenobjekten zurück, wobei jedes Task -Objekt ein JSON -Array von Subtask -Objekten nistet. Zum Beispiel,

[{
  "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"}
  ]
}]

Ein anderer Webdienst ermöglicht es mir, den Status einer bestimmten Subtask in einer bestimmten Aufgabe zu ändern, und sieht so aus:/tasks/45002/Unteraufgaben/1/Status/rot [beiseite - ich beabsichtige, diese in einen postbasierten HTTP -Dienst zu ändern Aber die aktuelle Implementierung ist einfacher beim Debuggen

Ich habe die folgenden Klassen in meiner JS -App:

Subtask -Modell und Subtasksammlung

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

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

Aufgabenmodell mit einer verschachtelten Instanz einer Subtask -Sammlung

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 
});

Aufgabenansicht, um das Element zu rendern und auf Änderungsereignisse auf das Modell zu hören

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!");
  }

});

Wenn die App startet, werde ich eine Task -Collection (verwende die Daten aus dem oben aufgeführten ersten Webdienst), binden Sie einen Hörer für die Änderung von Ereignissen an die TaskCollection und richten Sie eine wiederkehrende SetTimeout an die TaskCollection -Instanz ein.

...

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);

...

Alles wird beim ersten Mal erwartet. Aber zu diesem Zeitpunkt würde ich erwarten, dass entweder (oder beides) ein Sammelwechsel oder ein Modelländerungsereignis entlassen werden soll, wenn ich den Status einer Subtask mit meinem zweiten Webdienst ändere, dies ist jedoch nicht der Fall.

Lustigerweise habe ich Änderungsereignisse zum Feuer bekommen, wenn ich einen hinzugefügt habe zusätzlich Nist der Nistung, wobei der Webdienst ein einzelnes Modell zurückgibt, zum Beispiel:

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

Aber das scheint klugey ... und ich fürchte, ich habe meine App nicht richtig archiviert. Ich werde mehr Code einfügen, wenn er hilft, aber diese Frage ist bereits eher ausführlich.

Gedanken?

War es hilfreich?

Lösung

Sie hören die Ereignisse auf Ihren Aufgaben, nicht auf Ihre Unteraufgaben. Wenn Sie möchten, dass Ihre Aufgabe auch die Ereignisse für Ihre Unteraufgaben übertragen, sollten Sie in Ihrer Aufgabe so etwas tun.

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) });
});

Möglicherweise möchten Sie die Bindungen auch nach einem Aktualisierungsereignis aktualisieren. Auf diese Weise, wenn ein Änderungsereignis im Subtask -Modell auftritt, löst das Task -Modell auch ein Änderungsmodell aus.

Das Backbone sendet erst nach einem Abruf ein Aktualisierungsereignis. Sie werden nicht über eine Änderung eines bestimmten Modells informiert. Schauen Sie sich die Fetch -Funktion der Sammlung an:

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

Es wird standardmäßig aktualisiert. Hier ist die Aktualisierungsfunktion:

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;
}

Es wird alle Modelle zur Sammlung leise (ohne Ereignisse) hinzugefügt und dann ein Aktualisierungsereignis ausgelöst, aber nicht geänderte Elemente identifiziert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top