问题
I'm setting up a master-detail interface with two routes. The parent route houses an EventSource stream that regularly updates it's model.
I'm trying to make it so when the parent route's model suffers a change on any of its items, if the current detail view is displaying any of the changed items then it should be updated.
I'm currently trying to make a binding on the receptor
route to receptores
's controller's model and observing that:
Edited per blessenm's suggestions:
var App = Ember.Application.create({
rootElement: '#content'
});
App.Router.map(function() {
this.resource('receptores', {path: '/'}, function() {
this.resource('receptor', {path: ':user_id'});
});
});
App.ReceptoresRoute = Ember.Route.extend({
model: function() {
var deferredData = Ember.Deferred.create();
var data = [];
var sse = new EventSource('/monitoreo/receptores/push');
sse.addEventListener('update-receptores', function(e) {
var receptores = JSON.parse(e.data);
receptores.forEach(function(r) {
var item = data.findBy('id', r.id);
if (typeof(item) != 'undefined') {
data.replace(data.indexOf(item), 1, [r]);
} else {
data.pushObject(r);
}
});
deferredData.resolve(data);
});
sse.addEventListener('ping', function(e) {
console.log('ping');
});
return deferredData;
}
});
App.ReceptorRoute = Ember.Route.extend({
model: function(params) {
return this.modelFor('receptores').findBy('id', params.user_id);
}
});
App.ReceptorController = Ember.ObjectController.extend({
needs: ['receptores'],
parentModelBinding: Ember.Binding.oneWay('controllers.receptores.model'),
parentModelDidChange: function() { // never fires
console.log('changed');
this.set('model', this.modelFor('receptores').findBy('id', this.get('model').user_id));
}.observes('parentModel')
});
This is what I have so far. What happens is parentModelDidChange never fires. Using chrome I inspected receptor
's controller and a parentModel
property is never set, which I interpret as the binding not working.
I have a feeling I need to set up the model changes on the receptores
controller and not its route, but when I try the following I get the exception Assertion Failed: The value that #each loops over must be an Array. You passed <Ember.Deferred:ember338>
:
App.ReceptoresRoute = Ember.Route.extend({
setupController: function(controller) {
// same as the previous model hook
...
controller.set('model', deferredData);
}
});
My current solution. I took the EventSource out of the receptores
route and placed it in the global scope. Added an event listener to it from the receptor
controller's init
hook.
It seems to me that this should not be necessary. There should be a way to bind the child controller's model to the corresponding item in the parent route's array model. Changes on that source item should be reflected on the child immediately, but I guess that depends on the application's design as well.
var App = Ember.Application.create({
rootElement: '#content'
});
App.Router.map(function() {
this.resource('receptores', {path: '/'}, function() {
this.resource('receptor', {path: ':user_id'});
});
});
var sse = new EventSource('/monitoreo/receptores/push');
App.ReceptoresRoute = Ember.Route.extend({
model: function() {
var deferredData = Ember.Deferred.create();
var data = [];
sse.addEventListener('update-receptores', function(e) {
var receptores = JSON.parse(e.data);
receptores.forEach(function(r) {
var item = data.findBy('id', r.id);
if (typeof(item) != 'undefined') {
data.replace(data.indexOf(item), 1, [r]);
} else {
data.pushObject(r);
}
});
deferredData.resolve(data);
});
sse.addEventListener('ping', function(e) {
console.log('ping');
});
return deferredData;
}
});
App.ReceptorRoute = Ember.Route.extend({
model: function(params) {
return this.modelFor('receptores').findBy('id', params.user_id);
}
});
App.ReceptorController = Ember.ObjectController.extend({
init: function() {
var self = this;
sse.addEventListener('update-receptores', function(e) {
var current_id = self.get('model').id;
JSON.parse(e.data).forEach(function(r) {
if (r.id == current_id) {
self.set('model', r);
}
});
});
}
});
来源:https://stackoverflow.com/questions/23841178/emberjs-observe-parent-routes-model-and-change-child-routes-model-accordingly