我正在寻找一些关于为基本上有两个部分的 RoR 应用程序设计上述内容的建议:
1) 管理员表单生成器 2) 最终用户表单(由管理员在第 1 步中创建)
我已经对我想要的 JQuery 表单(最终结果)进行了原型(prototype)设计,它使用“渐进式披露”(类似于《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
基本上,管理员可以命名输入项,我将其用于 div id 等。鉴于我有许多输入类型(选择下拉列表、文本区域、带子项的输入,例如带有复选框的输入类型文本,选中后,打开一个数据网格,可以通过对话框弹出表单添加/删除项目等),我想避免像上面的示例中那样的“硬连线”构建方法。另外,如果允许调用者负责输入值选择(当他们传递输入 params 参数时就已经发生了),并且还负责构建器本身,那就太好了。
我对函数式编程很陌生,但我正在考虑一些对调用者传递“构建器”lambda 的影响,该函数使用输入参数构建他们需要的特定表单输入:
builder_lambda.call(input_params)
但是当我想到这一点时,似乎 lambda 看起来与 Jquery 模块已经在做的事情非常相似。是的,调用者将能够根据自己的喜好创建自定义构建器,但是我的模块方法真正要做的是什么!它将提供什么值(value)?
有时我还需要将这些输入连接到特定的事件处理程序。也许可能有一个 lamda 数组、一个构建器和一个添加事件处理程序,例如:
builder_lambda.call(input_params)
add_event_handlers_lambda.call(input_params)
我走在正确的道路上吗?抱歉,如果我胡言乱语,但我显然无法将这个问题分解为“Ruby-istic”解决方案,并且对于更动态的方法的想法将不胜感激。
编辑:这对我有帮助:Obie Fernandez DSL Development PDF
请您参考如下方法:
这听起来可能与你的想法相反,但我认为你正在努力解决这个问题,因为你想要的部分是重新发明轮子(创建一种元语言,其中你正在使用的框架已经提供了工具)。
我的方法是这样的:
使用某种 javascript 模板引擎(我的选择: Handlebars 或 jQuery.tmpl )为您的部分(在您的 View 中)创建 HTML 模板。还没有 build 者。
<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>
然后在你的 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')
然后您就拥有了表单所需的每一段 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') })
我的观点是:尝试专注于应用程序的“业务逻辑”,并以简化其余部分为目标(套用 Joel Spolsky 的话:深切关注您的核心能力并尝试外包/伪造其余部分)。
当然,这只是一个非常粗略的草案,我将采取并从这里完善它的方法(这里有一些重复,可以重构)。
