Socket.IO与Ember和Ember-Data的结合应用

18

我一直在探索,但找不到使用socket.io的最新ember(1.0.0-rc.1)和ember-data(revision 11)的示例。我尝试了类似这样的东西。

App.ApplicationRoute = Ember.Route.extend({
  setupController: function(controller, data) {
    var socket = io.connect(),
        self = this;
    socket.on('apartment/new', function(apartment) {
      var apt = App.Apartment.createRecord(apartment);
      self.controllerFor('apartments').pushObject(apt);
    });
  }
});

这实际上将创建一个新的模型类,将对象推送到控制器,并创建一个新的li,但值不会呈现。

<ul class="list-view">
{{#each apartment in controller}}
    <li>
      {{#linkTo 'apartment' apartment }}
        <span class="date">{{date apartment.date}}</span>
        {{apartment.title}}
      {{/linkTo}}
    </li>
{{/each}}
</ul>

这是否与运行循环有关?如何强制值进行渲染?或者有更好的方法吗?

2个回答

15

有一个非常简单的解决方案,我在我的一些应用中使用它。您可以为套接字设置一个通用回调函数并接受任何类型的数据。

callback: function(message) {
  // this is better than just `eval`
  var type = Ember.get(Ember.lookup, message.type);
  store.load(type, message.data);
}

或者这里是专门为您的使用情况量身定制的

socket.on('apartment/new', function(apartment) {
  store.load(App.Apartment, apartment);
});

使用store.load将记录数据直接加载到标识映射中。还有loadMany用于加载多个记录。


这会导致我遇到的同样问题(只是在文档中放置了一个空记录)。此外,您需要使用“var store = this.get('store');”引用“store”。 - Chad
公寓:{...}。它只是对象记录,不是数组记录。 - Chad
@Chad,你的做法是错误的,因为你已经指定了 App.Apartment,所以你只需要提供平面图数据,而不是整个 apartment: { ... },只需要 { ... } 就可以了。 - Jakub Arnold
明白了。现在已经搞定了。那么,存储中是否有类似于 unshift() 的方法,可以将数据推送到列表的开头? - Chad
在最新的ED(1.1.2)中,我认为您需要使用store.pushPayload(type, payload),它会插入原始数据。API说它是push,但在代码中是pushPayload。 - knownasilya
显示剩余5条评论

1

Ember CLIember socketscoffescript

我只接触Ember一个月,所以不能保证这是最好的方法,但我已经设置了一个带有Socket.io和Ember Data的Ember CLI项目。以下内容基于我的工作代码,但以下内容未经测试。我认为你需要的99%都在这里了。祝你好运解决问题!

.jshintrc - 如果你不包含EmberSockets,Ember服务将会警告你。

{
  "predef": {
  "document": true,
  "window": true,
  "nameofprojectENV": true,
  "EmberSockets": true
  },
  ...
}

Brocfile.js - 导入 Ember Sockets

var EmberApp = require('ember-cli/lib/broccoli/ember-app');

var app = new EmberApp();

// change this path to where ember-sockets.js is
app.import('vendor/ember-sockets/package/ember-sockets.js');

module.exports = app.toTree();

app.js - 请记得用实际项目名称替换“nameofproject”

import Ember from 'ember';
import Resolver from 'ember/resolver';
import loadInitializers from 'ember/load-initializers';

Ember.MODEL_FACTORY_INJECTIONS = true;

// every controller using ember sockets must be listed here in the controllers array
var Socket = EmberSockets.extend({
    host: 'example.local',
    port: 8080,
    controllers: [
        'example'
        // more controllers here
    ]
});

var App = Ember.Application.extend({
    modulePrefix: 'nameofproject',
    Resolver: Resolver,
    Socket: Socket
});

loadInitializers(App, 'nameofproject');

export default App;

router.coffee - 记得用实际项目名称替换nameofproject

`import Ember from 'ember'`

Router = Ember.Router.extend
    location: nameofprojectENV.locationType

Router.map ->
    @route 'example'

`export default Router`

models/example.coffee

`import DS from 'ember-data'`

Example = DS.Model.extend
    name: DS.attr('string')

`export default Example`

routes/example.coffee

`import Ember from 'ember'`

ExampleRoute = Ember.Route.extend
    # set model to be all example records
    model: ->
        @store.all('example')

    setupController: (controller, model) ->
        controller.set('model', model)

`export default ExampleRoute`

controllers/example.coffee

`import Ember from 'ember'`

ExampleController = Ember.Controller.extend

#### properties

examples: (->
    # @get('content') gets the model, which in this case, is example (set in route)
    @get('content')
).property('content') # watching the model like this might not be right?

#### methods
getExamples: ->
    @socket.emit 'pub',
        # whatever data you need to pass to the server
        data : {examples: true}
        # name of the event you want the data returned on
        event: "getExamples"

#### sockets
sockets:
    # returns examples from server
    getExamples: (data) ->
        # log the data for fun, also to see that you are getting data back
        console.log data
        # set controller to @, which is the same as this.
        controller = @

        # get your array of examples from JSON returned from server
        examples = data.examples

        examples.forEach (example) ->
            # controller instead of @, or it doesn't work
            controller.store.push 'example',
                # you need ids or this will not work
                id: example.id
                name: example.name

`export default ExampleController`

templates/example.coffee

{{#each example in examples}}
    {{example.id}} {{example.name}}
{{/each}}

<button {{action getExamples}}>Get Examples</button>

我建议使用Chrome Ember Inspector进行故障排除。你还可以查看数据模型和记录等其他内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接