【问题标题】:Ember.js with Socket.ioEmber.js 与 Socket.io
【发布时间】:2014-02-24 03:24:18
【问题描述】:

我试图在我的节点应用程序视图中实现一个简单的 Ember 应用程序。我知道 Ember 已设置并且我的套接字工作正常,现在唯一的问题是数据似乎没有被返回,即使它正在被检索。

这是我所拥有的:

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

App.Router.map(function() {
  // put your routes here
});

App.IndexRoute = Ember.Route.extend({
  model: function() {
    async.waterfall([
      function (callback) {
        socket.emit('getUserList', { data: null }); 
        callback(null, '');
      }, function (res, callback) {
        var userList = new Array();
        socket.on('recieveUserList', function (data) {
          for(var i=0; i<data.userList.length; i++) {
            userList.push(data.userList[i].name);
          }
        });
        callback(null, userList);
      }
    ], function (err, result) {
      return result;
    });
  }
});

现在如果我 console.log(results) 我回来 ['John Smith', 'Jane Doe'] 但它不会在我的页面上打印出来:

<script type="text/x-handlebars">
  <ul>
  {{#each item in model}}
    <li>{{item}}</li>
  {{/each}}
  </ul>
</script>

通过查看示例,它应该可以工作,对吧?

编辑 这是小提琴http://jsfiddle.net/UJ4Su/

【问题讨论】:

  • 虽然很难,但请您用静态模型制作小提琴。

标签: javascript node.js sockets ember.js ejs


【解决方案1】:

修好你的小提琴

在你看来试试这个:

<script type="text/x-handlebars" data-template-name="index">
  <ul>
  {{#each item in model}}
    <li>{{item}}</li>
  {{/each}}
  </ul>
</script>

(注意此模板对索引路由的显式引用)

这是你的小提琴的更新版本:

示例:http://jsfiddle.net/UJ4Su/13/

请注意,此示例不适用于您的套接字,因为您没有返回承诺。由于您正在返回一个普通数组(从技术上讲,您没有返回任何内容,因为您在异步套接字调用之外没有返回调用),Ember 期望数据立即存在。请参阅下文了解如何解决此问题。

在路由中处理异步调用第 1 部分

由于您正在进行异步调用来填充用户列表,因此您需要先返回一个空的用户列表,然后在您的套接字事件解决时填充它。这是一个使用 setTimeout 来模拟套接字调用的异步性质的小提琴:

App.IndexRoute = Ember.Route.extend({
    model: function(){
      var data = Ember.A();  
      window.setTimeout(function(){
         data.pushObject('a');
         data.pushObject('b');
         data.pushObject('c');
      }, 1000);    
      return data;
    }
});

您还需要使用 Ember 数组(相对于原生 Javascript 数组),以便 Ember 可以观察数组的变化并为您更新模板。

示例:http://jsfiddle.net/UJ4Su/7/

(有关在 Ember 中利用异步路由的更多信息,请参阅此页面:http://emberjs.com/guides/routing/asynchronous-routing/

利用 Ember.Deferred 或 Ember.RSVP

以上内容非常简单,但如果您想进一步利用 Ember,那么我建议您直接使用 Ember.Deferred 或 RSVP Promises。 Ember.Deferred 是一个简单的 mixin,它充当一些 RSVP 功能(特别是 then()、resolve() 和 reject())的包装器。下面是一个使用 Deferred 的例子:

App.IndexRoute = Ember.Route.extend({
    model: function(){
      var deferredData = Ember.Deferred.create();          
      var data = [];
      window.setTimeout(function(){
         data.push('a');
         data.push('b');
         data.push('c');
         deferredData.resolve(data);
      }, 3000);    
      return deferredData;
    },
    actions: {
        loading: function(transition, originalRoute){      
           return true;   
        }
    }
});

基本上我们返回一个 Ember.Deferred 而不是 Ember 数组。在 Deferred 解决之前,Ember 将转换为加载状态。然后,您可以在检索数据时向用户显示加载数据消息(通过套接字或 AJAX)。这是一个有效的小提琴示例:

示例:http://jsfiddle.net/UJ4Su/10/

这是一个使用 Ember Promises 的示例:

示例:http://jsfiddle.net/UJ4Su/12/

更多关于加载/错误子状态的信息可以在这里找到:http://emberjs.com/guides/routing/loading-and-error-substates/

希望有帮助!

【讨论】:

  • 那行不通。如果我在其中添加带有对象usersApp.ApplicationController 并将模型更改为用户它可以工作,但我无法为App.ApplicationController 中的对象定义函数
  • 好的,所以我发现它与我的套接字有关。数据正在加载,但无论出于何种原因都没有加载到 ember 中。
  • @pattmorter,请使用您的 Fiddle 的修改版本查看更新后的答案。不能肯定地说这是否会解决你的套接字问题,因为小提琴不使用套接字(我知道这有点难)。如果您的插座仍有问题,请告诉我。
【解决方案2】:

2016 年实际情况:

使用ember-websockets

它可以满足您开箱即用的所有需求。

【讨论】:

    猜你喜欢
    • 2015-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-30
    相关资源
    最近更新 更多