Ember.js 在路由中使用store.query时通过websocket添加新数据

Ember.js 在路由中使用store.query时通过websocket添加新数据,ember.js,websocket,ember-data,Ember.js,Websocket,Ember Data,我的应用程序使用基于的websocket服务将新记录从API推送到应用商店。我希望这些新记录在添加时呈现在我的模板中 我有一个路由,其中模型钩子返回一个过滤的查询承诺: import Ember from 'ember'; const { get, inject, } = Ember; export default Ember.Route.extend({ socket: inject.service(), model(params) { return this.s

我的应用程序使用基于的websocket服务将新记录从API推送到应用商店。我希望这些新记录在添加时呈现在我的模板中

我有一个路由,其中模型钩子返回一个过滤的查询承诺:

import Ember from 'ember';

const {
  get,
  inject,
} = Ember;

export default Ember.Route.extend({
  socket: inject.service(),

  model(params) {
    return this.store.query('my-model', {filter: {date: params.date}})
  },

  afterModel() {
    get(this, 'socket').joinSchedule();
  },

  resetController() {
    get(this, 'socket').leaveSchedule();
  },

});
当通过websocket将新记录推送到存储时,由于
store.query
的工作方式,我的模板不会呈现这些记录。如果我将
store.query
更改为
store.findAll
,则会呈现新记录,但我希望我的路由仅基于日期查询参数加载所有记录的子集

似乎我唯一的选择就是在将新记录推送到存储时重新加载路由的模型。是否可以从服务中执行此操作?如果没有,是否有其他我可能想探索的方法

我的插座服务的相关部分如下:

import Ember from 'ember';
import PhoenixSocket from 'phoenix/services/phoenix-socket';

const {
  get,
  inject,
} = Ember;

export default PhoenixSocket.extend({
  session: inject.service(),
  store:   inject.service(),

  joinSchedule() {
    const channel = this.joinChannel(`v1:my-model`);

    channel.on('sync', (payload) => this._handleSync(payload));
  },

  _handleSync(payload) {
    get(this, 'store').pushPayload(payload);
  },
});

当您在套接字上收到消息时,可以从websocket服务触发事件,然后在路由中订阅它,然后调用refresh()重新加载模型。
还有-哪个重新运行实时阵列。

选项1
您可以使用订阅和分派事件。我为演示而创建

插座
服务中

  • socket
    应扩展
    Ember.events

途中,

  • 您可以订阅
    myModelDataLoaded
  • 要避免内存泄漏,需要关闭订阅,您可以在重置控制器或停用挂钩中执行。 resetController() { get(this, 'socket').leaveSchedule(); get(this, 'socket').off('myModelDataLoaded', this, this.refreshRoute); } 路由文件-定义用于刷新的操作
    刷新路由
    ,因为
    刷新
    仅在路由中可用

    import Ember from 'ember';
    
    const {
        get,
        inject,
    } = Ember;
    
    export default Ember.Route.extend({
        socket: inject.service(),
        model(params) {
            return this.store.query('my-model', { filter: { date: params.date } })
        },
    
        afterModel() {
            get(this, 'socket').joinSchedule();
        },
    
        resetController() {
            get(this, 'socket').leaveSchedule();
        },
        actions:{
            refreshRoute() {
                this.refresh();
            },
        }
    });
    

    这不是一种更好的方法,但是处理现有代码的一种方法是使用回调

    import Ember from 'ember';
    
    const {
     get,
     inject,
    } = Ember;
    
    export default Ember.Route.extend({
      socket: inject.service(),
    
      model(params) {
        return this.store.query('my-model', {filter: {date: params.date}})
      },
    
      afterModel() {
        let cb = (myModelRecord) => {
          this.get('model').push(myModelRecord);
        };
        get(this, 'socket').joinSchedule(cb);
      },
    
      resetController() {
        get(this, 'socket').leaveSchedule();
      },
    
    });
    
    套接字服务中的调用回调方法

     import Ember from 'ember';
     import PhoenixSocket from 'phoenix/services/phoenix-socket';
    
     const {
       get,
       inject,
     } = Ember;
    
     export default PhoenixSocket.extend({
       session: inject.service(),
       store:   inject.service(),
    
       joinSchedule(cb) {
         const channel = this.joinChannel(`v1:my-model`);
    
         channel.on('sync', (payload) => cb(this._handleSync(payload)));
       },
    
      _handleSync(payload) {
        return get(this, 'store').pushPayload(payload);
      },
    });
    

    感谢您的详细回复!根据@xoma在上面发布的回复,我最终做了您在选项1中提出的事情,但我会给您评分,因为您花了时间为将来的人们记录它。 resetController() { get(this, 'socket').leaveSchedule(); get(this, 'socket').off('myModelDataLoaded', this, this.refreshRoute); }
    import Ember from 'ember';
    const { computed } = Ember;
    export default Ember.Controller.extend({
        init() {
            this._super(...arguments);
            this.get('postModel');//this is just to trigger myModel computed property
        },
        postModel: computed(function() {
            return this.get('store').peekAll('post');
        }),
        postModelObserver: Ember.observer('postModel.[]', function() {
            this.send('refreshRoute');
        })
    });
    
    import Ember from 'ember';
    
    const {
        get,
        inject,
    } = Ember;
    
    export default Ember.Route.extend({
        socket: inject.service(),
        model(params) {
            return this.store.query('my-model', { filter: { date: params.date } })
        },
    
        afterModel() {
            get(this, 'socket').joinSchedule();
        },
    
        resetController() {
            get(this, 'socket').leaveSchedule();
        },
        actions:{
            refreshRoute() {
                this.refresh();
            },
        }
    });
    
    import Ember from 'ember';
    
    const {
     get,
     inject,
    } = Ember;
    
    export default Ember.Route.extend({
      socket: inject.service(),
    
      model(params) {
        return this.store.query('my-model', {filter: {date: params.date}})
      },
    
      afterModel() {
        let cb = (myModelRecord) => {
          this.get('model').push(myModelRecord);
        };
        get(this, 'socket').joinSchedule(cb);
      },
    
      resetController() {
        get(this, 'socket').leaveSchedule();
      },
    
    });
    
     import Ember from 'ember';
     import PhoenixSocket from 'phoenix/services/phoenix-socket';
    
     const {
       get,
       inject,
     } = Ember;
    
     export default PhoenixSocket.extend({
       session: inject.service(),
       store:   inject.service(),
    
       joinSchedule(cb) {
         const channel = this.joinChannel(`v1:my-model`);
    
         channel.on('sync', (payload) => cb(this._handleSync(payload)));
       },
    
      _handleSync(payload) {
        return get(this, 'store').pushPayload(payload);
      },
    });