加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 在rails app / scaffold中无限制嵌套添加/编辑

发布时间:2020-12-17 02:20:30 所属栏目:百科 来源:网络整理
导读:概述/型号 比方说,你有一个相当大的系统,有非常通用的模型(我们将在这个例子中使用三个) 地点(通用地址字段,类型,第1行,第2行,城镇城市等) 公司(通用公司领域,名称等) 联系人(通用联系人字段,tpye,姓名,职务名称等) 示例(rails_admin screenshot) 我发现在制
概述/型号

比方说,你有一个相当大的系统,有非常通用的模型(我们将在这个例子中使用三个)

>地点(通用地址字段,类型,第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
  end
end

由于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]        
  end
end

文件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"
   end
end

class MyModel < Mega
end

然后在一个巨型控制器:

def edit
   @mymodel = MyModel.find(params[MyModel.get_id_name])
end

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读