我有一个由rails后端驱动的Backbone应用程序.我有一个邀请资源,我可以通过向邀请控制器的创建操作发送POST请求来发送邀请.
我的Backbone模型看起来像这样(coffeescript):
class Invitation extends Backbone.Model urlRoot: '/invitations'
然后是表单发送邀请的模板.我试图尽可能接近普通的rails形式,因为看起来Rails最好处理:
<form action="/invitations" accept-charset="UTF-8" id="new_invitation" class="new_invitation" method="post"> <input id="invitation_recipient_name" class="invitation_recipient_name" type="text" name="invitation[recipient_name]" /> <input id="invitation_recipient_email" class="invitation_recipient_email" type="text" name="invitation[recipient_email]" /> <input type="submit" class="btn primary" name="commit" id="invite" value="Send Invitation" /> </form>
这是我的模型和模板的Backbone View
class InvitationView extends Backbone.View # this is the template shown above template: JST['backbone/templates/invitation'] events: 'click #invite': 'sendInvite' render: -> $(this.el).html this.template() this sendInvite: (e) -> e.preventDefault() name = this.$('#invitation_recipient_name') email = this.$('#invitation_recipient_email') this.model.save recipient_name: name.val() recipient_email: email.val()
问题是当我单击提交按钮并调用sendInvite方法时,我的服务器接收具有以下结构的数据:
Parameters: {"recipient_name"=>"A name","recipient_email"=>"name@example.com","invitation"=>{"recipient_email"=>"name@example.com","recipient_name"=>"A name"}}
现在这实际上是有效的,因为我的邀请#create动作期望使用以下形式的参数:params [:invitations],这是rails的标准.然而,在请求中发送两次名称和电子邮件的事实似乎表明我的设置出了问题.
我做错了什么或这是对的吗?
如果有人想看到它,这是我的控制器动作:
# POST /invitations def create @invitation = current_user.sent_invitations.new params[:invitation] respond_to do |format| if @invitation.save format.json { render_for_api :invitation,json: @invitation,status: :created } else format.json { render json: @invitation.errors,status: :unproccessible_entity } end end end
编辑如果我设置属性并在保存之前记录它,这就是我的邀请模型:
Invitation _changed: false _changing: false _escapedAttributes: Object __proto__: Object _prevIoUsAttributes: Object recipient_email: "dave@example.com" recipient_name: "Dave" __proto__: Object attributes: Object recipient_email: "dave@example.com" recipient_name: "Dave" __proto__: Object cid: "c17" __proto__: ctor
sendInvite: (e) -> e.preventDefault() name = @$('#invitation_recipient_name') email = @$('#invitation_recipient_email') @model.set recipient_name: name.val(),recipient_email: email.val() console.log "THe model to save",@model
编辑2
这就是我在路由器中实例化我的视图的方式.我应该如何更改这一点,以便Backbone自动跟踪我的模型属性,即使我没有从服务器获取和设置它们?
var TeamRouter = Backbone.Router.extend({ routes: { 'members': 'members' },members: function() { @invite = new MoveOutOrg.Models.Invitation(); @inviteView = new MoveOutOrg.Views.InvitationView({ model: @invite }); $('#stage').append(@inviteView.render().el); } });
解决方法
params [:recipient_name]和params [:recipient_email]字段是您调用model.save()的结果.传入的参数是可选的.如果已使用正确的值创建模型,则无需传递任何要保存的内容.缺少的部分是你如何实例化视图.
此外,我将事件更改为“提交#new_invitation”.它更具描述性.您关心提交的表单…而不是他们点击了按钮.它还捕获了他们提交表单而不单击按钮的情况(例如按Enter键).
initialize: -> @model.bind('change',@render)
要记住的基本事情是模型事件通过集合和任何其他人聆听.因此,现在当您保存时,如果更改了任何属性,将触发更改事件,然后将导致视图重新呈现.