EmberJS:直接在主控制器上使用SSE支持的模型在主 - 详细应用中加载子URL

时间:2014-05-05 22:59:20

标签: ember.js frontend master-detail server-sent-events

我正在尝试使用两条路线之间的主 - 细节关系来开发这个单模块应用程序。主机应该具有最初加载的模型,并随后使用单个服务器端事件入口点进行更新。到目前为止,我有以下代码:

var App = Ember.Application.create({
    rootElement: '#content'
});

App.Router.map(function() {
    this.resource('receptores', {path: '/'}, function() {
        this.resource('receptor', {path: ':user_id'});
    });
});

App.ReceptoresController = Ember.Controller.extend({
    init: function() {
        var sse = new EventSource('/push');
        var controller = this;
        sse.addEventListener('update-hhs', function(e) {
            controller.set('model', JSON.parse(e.data).receptores);
        });
    }
});

App.ReceptorRoute = Ember.Route.extend({
    model: function(params) {
        return this.modelFor('receptores').findBy('id', params.user_id);
    }
});

加载'receptores'工作,目前数据加载正常。例如,单击链接到生成的链接http://localhost:5003/#/skkkd将加载“受体”路径和详细数据(详细信息只是主数据上加载的相同数据的子集)。

如果我尝试在详细网址上重新加载或直接输入http://localhost:5003/#/skkkd,我将获得以下例外情况:

Error while loading route: TypeError: Cannot read property 'findBy' of undefined
    at App.ReceptorRoute.Ember.Route.extend.model (http://localhost:5003/monitoreo/static/js/receptores.js:34:43)
    at superWrapper [as model] (http://localhost:5003/static/js/ember-1.5.1.js:1292:16)
    at Ember.Route.Ember.Object.extend.deserialize (http://localhost:5003/static/js/ember-1.5.1.js:36570:19)
    at http://localhost:5003/static/js/ember-1.5.1.js:32972:57
    at http://localhost:5003/static/js/ember-1.5.1.js:33464:19
    at invokeResolver (http://localhost:5003/static/js/ember-1.5.1.js:9646:9)
    at new Promise (http://localhost:5003/static/js/ember-1.5.1.js:9632:9)
    at Router.async (http://localhost:5003/static/js/ember-1.5.1.js:33463:16)
    at Object.HandlerInfo.runSharedModelHook (http://localhost:5003/static/js/ember-1.5.1.js:32971:16)
    at Object.UnresolvedHandlerInfoByParam.getModel (http://localhost:5003/static/js/ember-1.5.1.js:33058:19) 

我知道问题是没有为ReceptoresController调用init钩子。我认为我应该做的是在ReceptoresRoute或控制器上实现一个模型钩子,并通过jQuery.get()加载初始数据,并且只更新服务器端事件。但那我在哪里初始化SSE?

编辑: 事实证明我误解了模型钩子如何在子路径上工作。就我而言,我通常通过link-to链接查看详细信息页面,因此Ember已经为receptor提供了模型。在这种情况下永远不会调用模型钩子。只有在尝试直接访问详细信息页面时才会调用它。所以我的问题仍然存在。

我的整个问题归结为我应该放置SSE初始化的位置,这样两条路径都可以访问相同的模型,无论哪个都被加载。

1 个答案:

答案 0 :(得分:0)

好的,这是我的解决方案。这里有几个问题拼凑在一起。即https://stackoverflow.com/a/21988143/410224https://stackoverflow.com/a/21752808/410224。希望它可以帮助别人。

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('/push');
       sse.addEventListener('update-hhs', function(e) {
           var receptores = JSON.parse(e.data).receptores;
           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);
                   data.sortBy('full_name');
               }
           });
           deferredData.resolve(data);
       });
       return deferredData;
   }
});

App.ReceptorRoute = Ember.Route.extend({
    model: function(params) {
        return this.modelFor('receptores').findBy('id', params.user_id);
    }
});