使用Ruby和JQuery构建表单生成器

Rob*_*Rob 5 jquery closures functional-programming ruby-on-rails

我正在寻找一些关于为RoR应用程序设计上述内容的建议,该应用程序基本上有两个部分:

1)管理员表单构建器2)最终用户表单(由管理员在步骤1中创建)

我已经构建了我想要的JQuery表单(最终结果),它使用了"渐进式披露"(类似于JQuery in Action书中的Yehuda Katz的Bamboo示例),所以如果你点击一个项目,另一个项目可能会打开(例如点击"注册复选框"和另一个注册子表单显示).我也有rails应用程序实际构建了几个输入,如上所述.但是,我觉得我并没有真正利用Ruby的动态功能.例如,这是我的一个模块方法的一部分,它构建了一个特定的简单html输入:

module Levin 
  module EventReg 
    module Jquery

  def self.simple_registration_text(input_params)
    raise ArgumentError if input_params.nil?
    ip_id = input_params[:input_div_id] 
    simple_reg_input_html = '<p><label for="'
    simple_reg_input_html << "#{ip_id + '_label_id'}\">"
    ........<A BUNCH MORE CODE TO BUILD INPUT>........
    simple_reg_input_html << ' class="required"' unless input_params[:is_required].eql?("0")    
    simple_reg_input_html << '/></p>'
  end
Run Code Online (Sandbox Code Playgroud)

基本上,管理员可以命名输入项,我将其用于div id等.鉴于我有许多输入类型(选择下拉菜单,textareas,带子项的输入,如带有复选框的输入类型文本,如果选中,打开一个数据网格,可以通过对话框弹出窗口等添加/删除项目.),我想避免像上面的例子中那样"硬连接"构建方法.此外,允许调用者负责输入值选择(当它们传递输入参数参数时已经发生)以及构建器本身也是很好的.

我对函数式编程非常陌生,但我正在考虑调用者传入"构建器"lambda的影响,它使用输入参数构建他们需要的特定表单输入:

builder_lambda.call(input_params)

但是当我想到这一点时,似乎lambda看起来与Jquery模块已经做的非常相似.是的,调用者可以根据自己的喜好创建自定义构建器,但那么我的模块方法真的会做什么!它会提供什么价值?

我有时也需要将这些输入连接到特定的事件处理程序.也许可能有一系列lamdas,一个构建器和一个add事件处理程序,如:

builder_lambda.call(input_params)

add_event_handlers_lambda.call(input_params)

我是在正确的轨道上吗?对不起,如果我在闲聊,但我显然无法将此问题分解为"Ruby-istic"解决方案,并且非常感谢有关更具动态性的方法的想法.

编辑:这对我很有帮助:Obie Fernandez DSL Development PDF

gal*_*key 1

这听起来可能与你的想法相反,但我认为你正在努力解决这个问题,因为你想要的部分是重新发明轮子(创建一种元语言,其中你正在使用的框架已经提供了工具)。

我的方法是这样的:

使用某种 javascript 模板引擎(我的选择:HandlebarsjQuery.tmpl)为您的部分(在您的视图中)创建 HTML 模板。还没有建设者。

<script id="form-partial-registration" type="text/x-handlebars-template">
 <div class="registration_field field">
  <label for="{{field_id}}" id="label_for_{{field_id}}" class="label registration"></label>
  <input id="{{field_id}}" />
 </div>
</script> 
Run Code Online (Sandbox Code Playgroud)

然后在你的javascript中简单地编译模板

var form_builder = {templates:{}};
function compile_template(template_id, key) {
   form_builder.templates[key] = Handlebars.compile($("#" + template_id).html());
}
function render_template(template_id, data) {
   form_builder.templates[key](data);
}

// other stuff

compile_template('form-partial-registration', 'registration')
Run Code Online (Sandbox Code Playgroud)

那么您就拥有了表单所需的每一段 HTML 代码的集合,这些代码清楚地用 HTML 而不是 javascript 编写。然后使用它们:

function build_some_form(has_registration, has_expiration, event_handlers) {
  var form_content = [];
  var form_prefix = '...some_prefix...'

  // something optional
  if (has_registration) { 
    form_content.push( render_template('registration', {field_id:form_prefix + '_reg'}) )
  }

  // another optional 
  if (has_expiration) { 
    form_content.push( render_template('expiration', {field_id:form_prefix + '_exp'}) )
  }

  // put it into the form
  $('#some_form').append(form_content.join(''));


  // hook up handlers, in this example for onclick only
  for(var k in event_handlers) {
    $('#some_form #' + form_prefix + '_' + k ).click(event_handlers[k]);
  }
}

build_some_form(true, false, {reg: function() { alert('registration clicked') })
Run Code Online (Sandbox Code Playgroud)

我的观点是:尝试专注于应用程序的“业务逻辑”,并以简化其余部分为目标(套用 Joel Spolsky 的话:深切关注您的核心能力并尝试外包/伪造其余部分)。

当然,这只是一个非常粗略的草案,我将采取并从这里完善它的方法(这里有一些重复,可以重构)。