如何在Ember中与Rails进行通信

时间:2013-03-25 17:02:45

标签: ruby-on-rails ember.js ember-data

让我简要解释一下我的意思。我正在编写一个使用Ember和Rails的应用程序。每个员工都可以给其他同事一个工作。他不知道有多少人收到了。我只能知道我必须给予多少遗赠,以及我从其他人那里得到了多少。

但我真的不明白如何与Rails沟通。如图片胜过千言万语,请看一下: kudos app http://wstaw.org/m/2013/03/25/kudos.png

当应用程序启动时,我会加载指向/ users的用户列表。当前用户位于/ currentuser。当前用户的不同之处在于它有其他字段,如kudosReceived和kudosLeft。

让我们假设我想给乔添加一个工具。我点击一个按钮,然后,什么?假设当我去/ kudos / userid rails会发挥它的魔力。它只是增加了乔的工作。但我也想获得更新的当前用户数据(请记住,它位于/ currentuser)。

我应该寄什么?我应该首先在控制器上使用CREATE或UPDATE方法吗?如何获取当前用户的新数据?在回调中?或者我应该使用/ currentuser和GET。但什么时候?

这就是我现在所拥有的,但我完全不确定它是多么正确

// application.handlebars
<h1>My Kudos</h1>

<div id="kudos-content">
  <ul id="kudos-list">
    {{#with controllers.current}}
    <li>
      <p>{{firstName}} {{lastName}}</p>
      <p><img {{bindAttr src="imageUrl"}}  /></p>
      <p>received: {{kudosReceived}}</p>
      <p>left: {{kudosLeft}}</p>
    </li>
    {{/with}}
    {{#each user in controllers.users}}
    <li>
        <p>{{user.firstName}} {{user.lastName}}</p>
        <img {{bindAttr src="user.imageUrl"}}  />
        <a href="#" {{action "addKudo" user.id target="controller.controllers.kudo"}}>(+)</a>
    </li>
    {{/each}}
  </ul>
</div>

Sks.KudoController = Ember.ObjectController.extend({
    addKudo: function(userId) {
      // create a new record on a local transaction
      this.transaction = this.get('store').transaction();
      // don't really know what next
    }
});

下一个问题是如何在{{action}}

中使用/ kudo / userid

1 个答案:

答案 0 :(得分:1)

听起来没有必要将客户端中的Kudo视为除计数器之外的任何东西。客户端不知道任何特定Kudo的来源或其他任何内容。在这种情况下,将Kudo视为当前用户离开的-1个数的Kudo就足够了。

如果是这种情况,则为DS.Model创建Kudo类,担心关系,在商店中存储Kudo的所有内容,并将JSON发布到服务器是100 %矫枉过正。如果服务器不期望Kudo的JSON并且仅为目标用户创建Kudo服务器端,或者增加计数器,或者其他任何内容,那么这是特别的。

如果只是点击那个URL是必要的,听起来就像是,那么我建议只使用jQuery.ajax()来点击URL。我还假设一个成功的响应意味着当前用户少了一个kudosLeft,我只是在成功回调中处理它,而不是担心将currentUser模型同步到服务器。如果这不理想,您可以在currentUser上调用reload以手动获取新数据,假设服务器已在服务器端模型上跟踪kudosLeft

首先,将needs: ['current']添加到您的KudoController,以便您可以访问currentUser。

然后在addKudo

addKudo: function(user) {
    jQuery.post('/kudo/' + user.get('id'), jQuery.proxy(function () {
          this.decrementProperty('controllers.current.kudosLeft');
        }, this));
}

这假设CurrentControllerObjectController,因此它将该集合传递给content

最后,更新您的{{action}}以包含完整的User对象,而不仅仅是ID:

<a href="#" {{action "addKudo" user target="controller.controllers.kudo"}}>(+)</a>

一些注意事项:

(1)使用此方案可能会使客户端与服务器不同步,例如,如果用户打开了另一个应用程序副本并在那里发送Kudo。这可能是也可能不是问题。例如,在Stack Overflow中,当投票或接受的答案状态发生变化时,UI会动态更新。在你的情况下可能会接受,如果不重要的话,根本不关心保持每个小事情的同步。在这种情况下,您可能要做的是让您的/kudos端点返回特定的状态代码,如果客户端在用户没有剩余时尝试发送工具。 ajax调用的回调可以测试该状态并触发用户重新加载,或者只是将kudosLeft属性重置为0.

(2)像这样设置kudosLeft属性会将记录标记为脏,因此会在提交商店时导致更新。您可以做的是拥有一个计算属性,例如最初设置为displayKudosLeft属性的kudosLeft,但应用程序可以更改该属性以更新显示而不将记录标记为脏。

至于何时使用ember-data,以及何时使用$ .ajax,这取决于。您的API有多大以及它的RESTful程度如何?你使用active_model_serializers,它与ember-data有很好的搭配吗?您是否有很多需要在客户端反映出来的关系?您是否正在进行大量的“一次性”属性更新,或者为了产生影响而点击实际上并不期望接收JSON的API端点?

有大量的应用程序(或者至少有一个)不使用ember-data并且做得很好。例如,话语在$.ajax周围使用了一个薄的包装,它就可以了。