0

我正在使用带有类别的jQuery Autocomplete,我使用了运行良好的演示代码,现在我正在尝试用我的数据库中的数据填充下拉列表。我在我的视图中使用了这段代码:

:javascript
  $(function() {
      var data = [
          - Datasheet.find(:all).each do |ds|
            { label: "#{ds.title}", category: "Data Sheets" },
          - Brochure.find(:all).each do |br|
            { label: "#{br.title}", category: "Brochures" },

        $( "#search" ).catcomplete({
          delay: 0,
          source: data
      });
  });

但我得到了错误undefined local variable or method 'ds' for #<#<Class:0x00000005c95a18>:0x00000005c8d570>

我不确定是不是因为我将haml与javascript混合在一起?还有其他方法吗?在我看来,只有一个名为搜索的文本字段,它与演示代码一起使用。

4

1 回答 1

2

过滤器中的代码,例如:javascript不被视为 Haml,它只是通过过滤器馈送的字符串,因此-不会=像在 Haml 的其余部分中那样工作。不过,您可以使用插值(即#{...}块)。事实上,这就是导致你的错误的原因——在"#{ds.title}"Haml 中试图评估ds,但不是在传递给的块的上下文中Datasheet.find

#{}块可以跨越多行,因此您可以将代码更改为以下内容:

:javascript
  $(function() {
      var data = [
          #{
          (Datasheet.find(:all).map do |ds|
            "{ label: \"#{ds.title}\", category: \"Data Sheets\" }"
          end +
          Brochure.find(:all).map do |br|
            "{ label: \"#{br.title}\", category: \"Brochures\" }"
          end).join(',')
          }
      ];

      $( "#search" ).catcomplete({
        delay: 0,
        source: data
      });
  });

这里不是使用each迭代每个数组,而是map创建一个新数组,然后使用+将两个数组相加,最后使用join(',')将它们组合成一个插入页面的字符串。

然而,这是一段非常丑陋和笨拙的代码。在这种情况下,更好的解决方案是将创建数组的代码提取到帮助程序中,并从您的 Haml 中调用帮助程序。

帮手:

def datasheet_array
  Datasheet.find(:all).map do |ds|
    "{ label: \"#{ds.title}\", category: \"Data Sheets\" }"
  end
end

def brochure_array
  Brochure.find(:all).map do |br|
    "{ label: \"#{br.title}\", category: \"Brochures\" }"
  end
end

def array_for_js
  "[#{(datasheet_array + brochure_array).join(',')}]"
end

然后你的 Haml 可以更清晰:

:javascript
  $(function() {
      var data = #{array_for_js};

      $( "#search" ).catcomplete({
        delay: 0,
        source: data
      });
  });
于 2012-12-01T14:15:44.077 回答