Rails - 如何将javascript变量放入erb代码

时间:2015-11-25 18:45:32

标签: javascript ruby-on-rails

我见过一些类似的问题,但仍然不知道如何实现我的目标。 我想做那件事:

  1. 使用div表示的产品显示模式。
  2. 用户选择一些产品(我将.active类添加到所选产品中)
  3. 然后我使用jQuery来制作所选产品ID的数组。
  4. 最后我想为每个产品创建div,其中包括一些关于此产品的数据库信息。我正在使用js .append()来做到这一点。这是一个问题。
  5. 此代码在我的脚本标记中,视图正确。

        var chosen_products_array;
    
        $('.product-to-choose').click(function() {
            $(this).toggleClass("active");
            $(this).find('i').toggleClass("visible");
        });
    
        $('#chosen-products-confirm').click(function() {
            var chosen_products = $('.product-to-choose.active');
            chosen_products_array = jQuery.makeArray( chosen_products );
        });
    
        $('#confirm').click(function() {
    
            var textToInsert = '<div><h4>Products:</h4>';
            $.each(chosen_products_array, function(count, item) {
                var id = $(item).attr('id').substr(8); // id is product_number
                textToInsert += '<div><li name="chosen-product"> <%= current_user.products.find(' + id +').name %></li></div>';
            });
            textToInsert += '</div>';
            $('#div-example').append(textToInsert);
        });
    

    我的控制器创建动作:

    def create
    @meal = current_user.meals.build(meal_params)
    if @meal.save
      current_user.type_tags.each do |type_tag|
        key = "type#{type_tag.id}"
        if params[key]
          @meal.type_tags << type_tag # zapis do bazy danych
        end
      end
      flash[:success] = "Create new meal!"
      redirect_to meals_path
    else
      #render 'meals/new'
    end
    

    此行生成错误:

    textToInsert += '<div><li name="chosen-product"> <%= current_user.products.find(' + id +').name %></li></div>';
    

    错误:

    Couldn't find Product with 'id'=+id+ [WHERE "products"."user_id" = ?]
    

    我知道将js变量传递给rails erb存在问题,但在这种情况下如何解决?我也试过gon。

    在我的控制器中,我补充道:

    gon.products = current_user.products
    

    然后尝试

    alert(gon.products)
    

    没关系 - 对象数组,但是当我尝试

    alert(gon.products.find(1))
    

    它不起作用。

    你知道我怎么能把这个javascript id变量放到erb代码中?或者可能有任何不同的解决方案?

3 个答案:

答案 0 :(得分:1)

可能最好的方法是添加一个远程表单(可能是隐藏的),发布你想要的任何内容(javascript值),然后由控制器处理。然后你可以用js视图渲染它。

这可能是最“类似轨道”的解决方案。

以下是一些代码:

在路线中:

resource :my_form, only: :create

在视图中:

<%= form_tag(my_form_path, remote: true, method: :post) do %>
  <%= hidden_field_tag :val %>
<% end %>

您可以通过javascript动态更改val,并随时提交表单。

然后,在控制器中你有这样的东西:

respond_to :js

def create
  # do something with params['val']
  @my_val = params['val']
end

您还可以添加create.js.erb视图,您可以在其中添加一些可以使用控制器中创建的任何实例变量的javascript。

//create.js.erb
$('#someElement').html('<%= @my_val %>');

让我强调,如果不清楚,表单是远程(ajax),那么它将在后台发送,并且不会重新加载页面。

当浏览器收到响应时,它可能包含您决定呈现的任何javascript(create.js.erb的内容),然后浏览器执行该javascript。

因此,您可以添加任何jquery命令,其中的参数由rails动态更改,或者您也可以渲染html partials并用它们替换任何元素,如下所示:

//create.js.erb
$('#my_id').html('<%= j(render partial: 'my_form/_some_partial.html.erb', locals: { my_val: @my_val }) %>');

有关Working with JavaScript in Rails

的更多详情

更新

另一个更低但更简单的解决方案是始终渲染所有产品,但最初隐藏它们,然后根据需要通过jQuery显示它们。您只需要为这些产品添加适当的css类或数据属性,以及用于选择它们的链接。

答案 1 :(得分:0)

问题是在浏览器甚至提取javascript文件之前在服务器上评估erb代码,因此使用这种方式没有意义。建议您仅在javascript中使用erb来处理asset_path

等简单的事情

答案 2 :(得分:0)

我认为首先让你的模型对浏览器可见为js变量(json对象)。在视图文件末尾有下面的内容(下面是haml语法):

:javascript

   var userProducts        = #{@current_user.products.to_json};

然后在javascript表达式中使用它