比方说,你有一个相当大的系统,有非常通用的模型(我们将在这个例子中使用三个)
>地点(通用地址字段,类型,第1行,第2行,城镇城市等)
>公司(通用公司领域,名称等)
>联系人(通用联系人字段,tpye,姓名,职务名称等)
示例(rails_admin screenshot)
我发现在制作这样的系统时,我总是遇到同样的问题.我点击了公司的添加按钮(例如我现在已经加载了表格部分等),我通过添加公司的一部分,发现我需要的位置不在系统中.我想快速打开一个模态窗口,添加位置,然后通过jquery或其他东西更新选择.太棒了,没什么太难的,而且已经在像rails_admin这样的系统中完成了(见下面的截图):
http://www.server1-breakfrom.com/nestedaddexample.jpg
当处理一个级别的嵌套时,这一切都很好,并且一般来说,当处理这个问题时,所有这些都很好(因为你可以在这个时候编写能力).但是,我正在建立一个系统,这个系统本身几乎需要一个框架,因为我需要超过50%的模型.我需要能够在模型/控制器中动态添加各种选项,并让表单动态生成相关按钮.
其他问题
>模态内部/之上的模态 – 添加联系人时,单击添加他们的公司,在这些新公司添加表单中然后您想要添加一个位置:繁荣,模态在模态之上.
> jquery附加到select的哪个文本 – 您需要知道如何更新select元素并可能在屏幕上找到所有相关的select元素.添加公司可能会使用它的ID和它的名称,但是一个位置需要使用ID以及文本的line1,line2和towncity.
>模态中的验证(但我假设我们可以使用某种jquery,因为我们已经非常依赖它)
扩大问题
所以,除了问题:我是否过于复杂化并且有一个容易解决我的问题(我必须强调3个模型纯粹是例子,我有很多模型需要引用公司,例如,它不仅仅是一个联系人,所以’只需按需要编程’,将无法正常工作!).
或者,我应该拉开rails_admin并拉出我需要的位吗? (同样,他们还没有解决多重嵌套问题,所以我觉得从头开始可能会更好?).
解决方法 我遇到了类似的情况.我的解决方案可能在您的方案中存在性能问题,它不适合我,但它是一个低并发使用系统,只有300个用户.我做的是使用一个MEGA AJAX视图/表格!并根据需要使用JavaScript显示/隐藏.此技术要求您不要使用表单标记助手(即text_fIEld_tag而不是f.text_fIEld),您必须控制元素名称.
因此,首先要创建一个包含您最终需要的所有表单的视图.您必须区分它们,因此将每个元素放在具有唯一ID的div元素中.
<%= form_for @mega,:remote=>true do %> <div ID='main_part'> <%= render :partial => "main_part",:object=>@mega %> </div <div ID='subpart1'> <%= render :partial => "subpart1",:object=>@foobar,:locals=>{:ID=>@foobar.ID} %> </div <div ID='subpart2'> <%= render :partial => "subpart2",:object=>@barfoo,:locals=>{:ID=>@barfoo.ID} %> </div<% end %>
表单部分的一个示例,注意区分提交按钮:
<%= label_tag "main_part[name]","name" %><%= text_fIEld_tag "main_part[name]",main_part.name %><%= submit_tag "UPDATE",:name=>'main_part' %><%= hIDden_tag_fIEld "subpart1_ID",ID %><%= label_tag "subpart1[city]","City" %><%= text_fIEld_tag "subpart1[city]",subpart1.city%><%= submit_tag "ADD",:name=>'subpart1' %>
所以现在你需要一个大型控制器,因为这个表单发布到一个控制器动作.该控制器看起来只是顶级型号的常规控制器,但它需要为所有型号进行管理.
该控制器动作必须弄清楚点击了哪个提交按钮,即
def update if params[:main_part] # since I controlled the parameter naming I kNow what's in params[:main_part] # which is main_part[:name] @mega = MainThing.find(params[:ID]) @mega.attributes = params[:main_part] @mega.save # only for main_part is the ID valID,in every other case you have to # manually extract the ID elsif params[:subpart1] @subpart1_ID = params[:subpart1_ID] @foobar = Foobar.find(@subpart1_ID) @foobar.attrubutes = params[:subpart1] @foobar.save else endend
由于mega表单是remote => true,因此您需要创建一个JavaScript文件来重新加载所有表单部分,因此在app / vIEws / megas / update.Js.erb中:
$('#main_part').HTML('<%= escape_JavaScript(render :partial=> "main_part",:object=>@mega) %>');$('#subpart1').HTML('<%= escape_JavaScript(render :partial=> "subpart1",:object=>@foobar :locals=>{:ID=>@foobar.ID) %>');
现在这里是性能问题的来源.如果您注意到,如果我运行该JavaScript,它将期望定义所有这些实例变量,因此各种部分将呈现刷新任何由于更新而获得新值的选择标记.在我的情况下,我只是在一个前过滤器中加载它们,即
class MegaController < ApplicationController before_filter :load,:only=>[:edit] def load @mega = Mega.find(params[:ID]) @foobar = @mega.foobar @barfoo = @foobar.barfoo end
但你也可以不这样做,而是创建单独的JavaScript文件并在控制器中专门呈现它们,即
def update if params[:main_part] # do whatever... render :action=>'update_set1',:handler=>[:erb],:formats=>[:Js] elsif params[:subpart1] # do whatever render :action=>'update_set1',:formats=>[:Js] elsif params[:subpart2] # do whatever render :action=>'update_set2',:formats=>[:Js] endend
文件app / vIEws / mega / update_set1.Js.erb只会更新受@mega或@foobar更新影响的部分,update_set2.Js.erb会更新受@barfoo更新影响的部分.
最后一点,你的表单是remote => true,你怎么退出?假设你有:
<%= submit_tag 'Cancel',:name=>'cancel' %>
然后在控制器中你会做类似的事情:
def update if params[:cancel] render :Js=> "window.location = '/'" else # whatever.... end end
最后一步是添加JavaScript以根据需要显示/隐藏表单div,一个练习留给读者….
UPDATE
class Mega < ActiveRecord::Base def self.get_param_name self.class.name end def self.get_ID_name "#{self.class.name}_ID" endendclass MyModel < Megaend
然后在一个巨型控制器:
def edit @mymodel = MyModel.find(params[MyModel.get_ID_name])end总结
以上是内存溢出为你收集整理的ruby-on-rails – 在rails app / scaffold中无限制嵌套添加/编辑表单的好方法是什么?全部内容,希望文章能够帮你解决ruby-on-rails – 在rails app / scaffold中无限制嵌套添加/编辑表单的好方法是什么?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)