如何使用 JQuery 和 Rails 创建类似 Wufoo(表单构建器)的 Web 应用程序?

Posted

技术标签:

【中文标题】如何使用 JQuery 和 Rails 创建类似 Wufoo(表单构建器)的 Web 应用程序?【英文标题】:How to create a Wufoo-like (form builder) web application with JQuery and Rails? 【发布时间】:2011-06-12 15:48:27 【问题描述】:

我正在寻找一些关于如何在客户端使用 JQuery 在 Rails 3 应用程序中实现 Wufoo-like builder 的指导。基本上允许用户在“离线”模式下构建一些东西(在 Wufoo 的情况下是一个表单),然后通过单击“保存”按钮或类似按钮将所有用户编辑批量保存到服务器(例如,可能是由每 30 秒左右浏览一次)。

此时我倾向于使用 html5 本地存储。 “构建器”本质上将以 JSON 格式将用户编辑本地存储在浏览器本地存储中。单击“保存”按钮,然后将本地存储的内容 HTTP 以 JSON 格式发布到 Rails 应用程序。这听起来对吗?有什么意见、建议吗?

一些额外的注意事项/问题:

不支持 HTML5 的旧浏览器怎么办?是否应该有使用 cookie 存储的后备计划? 任何可以帮助解决这些问题的 JQuery 插件?例如抽象 HTML5 本地存储作为主存储,cookie 存储作为辅助/备用存储。 需要注意哪些特定于 Rails 的注意事项?

注意:以下问题专门针对 WYSIWYG 表单构建器,并没有真正提供任何好的解决方案。 Creating WYSIWYG form builder (á la Wufoo) in Rails

谢谢!

【问题讨论】:

我感觉你的问题——虽然肯定很有趣——表述得有点太模糊了。如果您能够将其分解成更小的部分并更详细​​地显示您所在的位置以及您撞墙的位置,那么人们可能会更好地帮助您。祝你好运! 谢谢。我发布了一个答案来更新我的进度。 【参考方案1】:

我在工作中一直在玩这个,我认为它可以让您在知道如何序列化和反序列化自身的 jquery 表单构建器上抢占先机。我认为它将表单序列化为字符串而不是 JSON,但这是一个开始。 http://www.botsko.net/blog/2009/04/07/jquery-form-builder-plugin/

谷歌搜索找到了我的sites.google.com/site/daveschindler/jquery-html5-storage-plugin,它说如果浏览器不支持它,它会将内容存储在HTML 5存储中,并回退到cookie。

另一个想法:如果使用本地存储的目标是让用户不丢失他们还不想发布的工作,那么另一种选择可能是实现单独的“保存”和“发布”按钮,这样您仍然可以保存用户在服务器端的工作,但让他们保留“草稿”,直到他们准备好发布,这样他们使用哪个浏览器或 PC 就无关紧要了。

希望这会有所帮助。

【讨论】:

谢谢。我正在使用 JSON,因此 XML 序列化/反序列化代码不会有太大帮助。不过,我非常喜欢建造者本身。将重复使用其中的一部分。【参考方案2】:

这是我最终实现的设计。我远未找到完整的解决方案,但我认为这是一个好的开始。

数据模型

在我的例子中,用户需要能够建立一个任务列表,其中任务可以有不同的类型和属性。任务还可以嵌入其他对象。在某种意义上类似于表单构建器,尽管我正在处理更深层次的嵌套对象。这里的关键是确保您的后端应用程序只公开与您的应用程序域相关的对象(在Domain Driven Design 的意义上),以便您的客户端代码在从服务器调用并在序列化它以准备保存之前。在这种情况下,我不得不对我的服务器端表示层进行一些更改,但结果我认为我的客户端代码更简洁,更专注于处理实际的用户事件。

数据序列化

我选择 JSON 作为数据交换格式。在客户端,我有两个处理数据序列化和反序列化的函数。实现非常简单(部分归功于我为公开域模型对象所做的一些更改)。我在下面粘贴了一个简化版本。唯一的挑战是 Rails 用来处理 PUT 请求的 _method 参数似乎不适用于 JSON Content-Type。见Using HTTP PUT to send JSON with Jquery and Rails 3

var todoList = ;

$.getJSON("/users/123/todolists/456.json", function(data) 
  loadTodoList(data);
  ...
);

function loadTodoList(data) 
  todoList = data.todoList;


function saveTodoList() 
  $.ajax(
    type: 'POST',
    url: "/users/123/todolists/456",
    data: JSON.stringify( todoList: todoList ),
    contentType: 'application/json',
    dataType: 'script', // could be "json", "html" too
    beforeSend: function(xhr)
      xhr.setRequestHeader("X-Http-Method-Override", "put");
    
  );

在服务器端,Rails 也可以轻松处理 JSON(JSON 的序列化和反序列化由框架自动且透明地执行)。我只是在我的 TodoList 模型上覆盖了 to_json() 方法,以避免来回传递无用的数据(例如 create_at、modified_at 属性)。在获取我的***对象(即 TodoList)时,还必须确保包含所有嵌套对象。

  # TodoListsController
  def show
    @todolist = TodoList.find_by_id(params[:id], :include => [:tasks, ...])
    respond_to do |format|
      format.json do
        render :json => @todolist.to_json
      end
    end
  end

  # TodoList model
  def to_json
    super(:only => :name,
          :include =>  :tasks =>  :only => [:name, :description, ...],
                                    :include => ... )
  end

客户端持久性

这里的目标是避免意外丢失尚未保存的用户编辑。到目前为止,我直接使用 HTML5 本地存储(localStorage 变量),但最终会寻找一个 jQuery 插件,如果不支持 HTML5,它会自动处理回退到 cookie 存储。

动态 HTML 生成

我依靠 jQuery Template 来生成 HTML。构建器的主要功能是动态生成 HTML,所以这个插件非常方便。我已经为我的待办事项列表模型的所有构建块定义了模板(例如任务、笔记……)。每当创建这些对象的新实例并需要渲染时,就会调用模板。

我认为这奠定了大部分基础。其余的主要是核心 javascript,用于处理与表单/todoList 构建器的所有用户交互。

【讨论】:

+1 - 这个答案真的很有帮助。我们有同样的要求。我能够从中得到一个很好的概述。但我想知道数据库结构的外观。你能帮我解决这个问题吗?你能发布数据库架构吗?这真的很有帮助。

以上是关于如何使用 JQuery 和 Rails 创建类似 Wufoo(表单构建器)的 Web 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

当没有找到与 Rails 的 JQuery 自动完成匹配时如何显示响应

Rails 3 & jQuery - 两者如何协同工作来创建 Web 应用程序?

如何创建类似于 javascript 节流/去抖动功能的 Rails/Ruby 方法

如何使用 Rails 5 + jQuery 保持通过 Turbolinks 提交的页面状态

Rails 4 使用 ajax、jquery、:remote => true 和 respond_to 渲染部分

如何从rails中的视图将值传递给jquery?