Rails通过knockout.js提交表单

时间:2012-04-25 23:18:37

标签: ruby-on-rails knockout.js

我有一个Rails 3.2应用程序,我已经开始附加了很多knockout.js绑定。我想以JSON格式将表单提交给我的Rails服务器。

我有一个有金额的交易表格

= form_for(@tran, :html => {"data-bind" => "submit: submitTrans"}) do |f|
    .field
        = f.label :date
        = f.date_select :date
    .field
        = f.label :voucher
        = f.number_field :voucher
    .field
        = f.label :amount
        = f.text_field :amount, "data-bind" => "value: amount, valueUpdate: 'afterkeydown', style: { background: amount() == 0 ? 'red' : 'white' }"
    .field
        = f.label :tax
        = f.text_field :tax, "data-bind" => "value: tax"
    .actions
        = f.submit 'Save'

这是我的淘汰代码:

#= require knockout

TranViewModel = ->
  # Observables
  self.amount = ko.observable("0")

  # Computed values
  self.tax = ko.computed(
    read: -> (self.amount() / 10).toFixed 2
    write: (value) -> value
    owner: this)


tranViewModel = new TranViewModel()

# Submit through AJAX
self.submitTrans = (formElement) ->
  alert ko.toJSON(tranViewModel)

# Apply keybindings on page load
$(document).ready (event) ->
  ko.applyBindings(tranViewModel)

当我像这样使用ko.toJSON时,我的警报框中会返回'undefined'。

我是否必须创建模型的实例? 如何以JSON格式获取所有表单属性并将其发布到我的rails route'/ transaction'?

淘汰赛文档描述了pushJSON功能,但该页面不再存在: http://knockoutjs.com/documentation/submit-binding.html

更新#1

我尝试手动发送json,这允许我创建一个对象

self.submitTrans = (formElement) ->
  json = JSON.parse('{"tran": {"amount": "9999"}}')
  $.post("/trans", json, (returnedData) ->
    alert returnedData)

更新#2

我尝试了许多方法将我的表单转换为JSON,以便使用$ .post

进行提交
self.submitTrans = (formElement) ->
  json = ko.toJSON(tranViewModel)
  $.post("/trans", json, (returnedData) ->
    alert returnedData)

这是未定义的。我将什么传递给ko.toJSON?

更新#3

我在淘汰赛网站上试过这个例子:

viewModel =
    firstName : ko.observable("Bert"),
    lastName : ko.observable("Smith"),
    pets : ko.observableArray(["Cat", "Dog", "Fish"]),
    type : "Customer"

self.submitTrans = (formElement) ->
  json = ko.toJSON(viewModel)
  $.post("/trans", json, (returnedData) ->
    alert returnedData)

这正确地将viewModel格式化为JSON。这是因为viewModel是一个对象而不是一个函数。但是,如果我将TranViewModel从函数更改为对象,则会破坏我的大量绑定。设置绑定的正确方法是什么?他们应该在一个对象还是一个函数中?

更新#4

我的例子: jsfiddle.net/p6Vcc/3 - 当点击提交时,ko.toJSON不会收集所有的formElements,我应该在所有字段中添加observable吗?

jsfiddle.net/p6Vcc/4 - 与上一个示例相同,但在coffeescript中重新编码,现在点击提交时,它只显示客户的姓氏,而不显示其他任何字段。

1 个答案:

答案 0 :(得分:1)

更新1 所以看看jsfiddle上面提供的咖啡脚本,coffeescript生成的javascript存在问题:

  viewModel = __bind(function() {
    this.firstName = ko.observable("Bert");
    return this.lastName = ko.observable("Smith");
  }, this);

Coffeescript总是返回最后一个语句,所以你必须在最后加一个@来“返回这个”

viewModel = =>
  @firstName = ko.observable("Bert")
  @lastName = ko.observable("Smith")
  @ 

结果javascript

  viewModel = __bind(function() {
    this.firstName = ko.observable("Bert");
    this.lastName = ko.observable("Smith");
    return this;
  }, this);

原始答案

我不确定你遇到麻烦的地方。我把你的代码放在一个jsfiddle中,它按预期工作。

http://jsfiddle.net/JasonMore/p6Vcc/2/

您能否更新小提琴以反映您遇到的问题?

<强>的Javascript

var viewModel = function() {
    this.firstName = ko.observable("Bert");
    this.lastName =ko.observable("Smith");
    this.pets = ko.observableArray(["Cat", "Dog", "Fish"]);
    this.type = "Customer";
};

var myViewModelInstance = new viewModel();

var jsonToPost = ko.toJSON(myViewModelInstance);

//alert(jsonToPost );

console.log(jsonToPost);