モデルの変更されたコレクションのイベントの変更予想通りに発射されない
-
14-10-2019 - |
質問
私は最初の「実際の」アプリケーションでbackbone.jsを使用しようとしています。特定のモデル変更イベントが予想されるように解雇されていない理由をデバッグするのに役立つ必要があります。
JSONからコレクションを作成した場合 配列 サーバーから、設定された間隔でfett()をfetch()では、コレクション内の個々のモデルが変更された場合に通知されません。バックボーンドキュメントは、そのような通知を生成する必要があることを示唆しています。私が得ると思われるのは、各フェッチの更新通知だけですが、これは役に立ちません。 otoh、JSONからモデルを作成した場合 物体 サーバーから、設定された間隔でモデルをfetch()をfetch()で、属性が変更されたときに変更通知を取得します。何か案は?
詳細
/employees/{username}/タスクの私のWebサービスは、各タスクオブジェクトがSubtaskオブジェクトのJSON配列をネストするJSONアレイのタスクオブジェクトを返します。例えば、
[{
"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"}
]
}]
別のWebサービスを使用すると、特定のタスクで特定のサブタスクのステータスを変更でき、次のようになります。 、しかし、現在の実装はデバッグが簡単です
JSアプリには次のクラスがあります。
サブタスクモデルとサブタスクコレクション
var Subtask = Backbone.Model.extend({});
var SubtaskCollection = Backbone.Collection.extend({
model: Subtask
});
サブタスクコレクションのネストされたインスタンスを備えたタスクモデル
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
});
アイテムをレンダリングし、モデルへの変更イベントを聞くタスクビュー
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!");
}
});
アプリが起動すると、タスクコレクションをインスタンス化し(上記の最初のWebサービスのデータを使用して)、リスナーを変更イベントのリスナーにタスクコレクションに結合し、fetch()the taskCollectionインスタンスに定期的なSetimeoutを設定します。
...
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);
...
すべてが最初に予想されるようにレンダリングされます。しかし、この時点では、2番目のWebサービスを使用してサブタスクのステータスを変更すると、コレクション変更イベントまたはモデル変更イベントが解雇されると予想されますが、これは発生しません。
面白いことに、私はそれを追加した場合、私は変化のイベントを発火させました 追加 ネスティングのレベル。たとえば、単一のモデルを返すWebサービス。
"employee":"pkaushik", "tasks":[{"id":45002,"subtasks":[{"id":1.....
しかし、これはklugeyのようです...そして、私は自分のアプリを正しく建設していないのではないかと心配しています。それが役立つ場合はもっとコードを含めますが、この質問はすでに冗談です。
考え?
解決
サブタスクではなく、タスクのイベントを聴いています。タスクにサブタスクのイベントを掲載したい場合は、タスクでこのようなことをする必要があります。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) });
});
リフレッシュイベントの後にバインディングを更新したいと思うかもしれません。これにより、Subtaskモデルで変更イベントが発生すると、タスクモデルも変更モデルをトリガーします。
Backboneは、フェッチの後に更新イベントを送信するだけで、特定のモデルの変更については通知されません。コレクションのフェッチ関数を見てください:
options.success = function(resp) {
collection[options.add ? 'add' : 'refresh'](collection.parse(resp), options);
if (success) success(collection, resp);
};
デフォルトで更新を呼び出します。これが更新機能です:
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;
}
すべてのモデルをコレクションに静かに(イベントなしで)追加し、更新イベントをトリガーしますが、変更された要素を識別しません。