【问题标题】:Creating helper tag with UJS使用 UJS 创建辅助标签
【发布时间】:2025-12-08 19:50:02
【问题描述】:

首先,对不起我的英语。我是巴西人,还在进步。

我想创建一个名为“collection_cascading_select”的辅助标签。 该助手类似于“collection_select”,但他还有一个名为“source”的参数。 “源”是视图中的另一个集合。

在“源”中选择其他选项时,需要运行 JavaScript 函数来获取其值。然后填充同意该值的“collection_cascading_select”集合。

这让人困惑!我在这个问题上一周了,我的巴西兄弟没有帮助我。

谢谢!

[编辑]

@萨莫

我得到了它的工作,但有一些变化。

var success = function(response) {

for (var item in response){

    var id = response[item].breed.id   <--------------------  
    var name = response[item].breed.name <-------------------  
    var option = $(document.createElement('option')).val(id).html(name)
    dependentDropDown.append(option)  
  }  
}

我不明白FOR IN 的工作原理。

【问题讨论】:

    标签: javascript ruby-on-rails ruby ajax ruby-on-rails-3


    【解决方案1】:

    听起来您正在寻找的答案是自定义表单生成器。您可以创建表单构建器并从 Rails 表单构建器继承,然后将该表单构建器设置为整个应用程序的默认值。然后您可以定义一个名为dependent_dropdown 或cascading_selection 等的元素。该元素可能会采用源下拉列表的ID。您的助手会输出一个 collection_select,但它也会输出一些 JavaScript,当源下拉列表更改时会触发 AJAX 调用。

    当然,您不必这样做。您可以只使用一个collection_select,将一些属性添加到源下拉列表(即:class =&gt; 'source_for_dependent', :dependent =&gt; some_id),然后在您的application.js 中连接一些JavaScript,以查找具有source_for_dependent 类的集合,以及当onchange 事件触发它从 dependent 属性中获取 id 并触发 AJAX 调用。

    无论哪种方式,这是您的 JavaScript 示例(使用 jQuery)

    $('select.source_for_dependent').change(function() {
      var id = // get the id of the dependent dropdown, perhaps by $(this).attr('dependent')
      var dependentDropDown = $('#' + id);
      dependentDropDown.empty();
      var success = function(response) {
        for (var item in response) {
          var option = $(document.createElement('option')).val(item.val).html(item.text);
          dependentDropDown.append(option);
        }
      }
    
      $.get('/some_controller/some_action/' + $(this).val(), success);
    }
    

    成功处理程序被传递到 jQuery 的 get 方法中。它将 JSON 响应作为参数。我们遍历响应,并为每个项目创建一个option,从项目中提取值和文本,并将其附加到相关下拉列表中。您的控制器可能如下所示:

    def some_action
      @obj = SomeClass.find(params[:id])
      respond_to do |format|
        format.js { render :json => @obj }
      end
    end
    

    编辑

    您的目标控制器由您决定。假设 Dropdown A 以资源 A 为目标,而 Dropdown B 以资源 B 为目标。A 类型的对象应该具有B 类型的对象列表。如果您要针对对象A 执行show 操作,那么对象Aas_json 方法需要包含其B 关联。 This article 显示了这方面的示例。

    否则,您可以针对资源 B 执行 index 操作。使B 成为A 的嵌套资源将是一种简单的方法来关闭A 的id 以获取所有B 类型的对象,这些对象具有指向A 的外键。

    【讨论】:

    • 当然,我的错。你必须给源下拉一个不同的类......我想不出一个好名字,也许是“source_for_dependent”或类似的东西。说,如果我的回答有帮助,那么投赞成票或绿色勾号怎么样? :)
    • 在 FOR IN 迭代中,ITEM 返回一个字符串,而不是一个对象。因为这个,我不能操纵数据。奇怪的是,我没有迭代就可以工作。其他事情......我需要在 $.get 中指定数据类型(json)才能工作。感谢您的宝贵帮助。
    • 您可以自行了解响应对象中包含的内容。在处理程序函数中设置断点并使用 firebug 对其进行检查将向您展示如何访问对象的属性。如果您需要关联,您可能必须覆盖模型中的 as_json 方法以包含它们。此外,还有一种方法可以指定所有 XHR 请求都接受 JSON,这样您就不必为每个 AJAX 调用指定它。见这里:railscasts.com/episodes/136-jquery
    • 我的电子邮件中没有收到我的(这个)问题的更新。奇数
    • “如果您需要关联,您可能必须在模型中覆盖 as_json 方法以包含它们。”。对不起,我不明白这个。