将Rails对象传递给Javascript

4

我已经使用Rails工作一段时间了,已经解决了一些问题,但是我正在努力解决这个问题。我有一组博客文章的数组,只渲染它们的标题。在控制器中,该对象看起来很简单:

@articles

在我的主页面上,我通过部分渲染它并仅显示标题。
<%= render 'shared/article_view', :collection => @articles %>

这使我在主页面上获得一系列文章列表。当我单击标题时,我想在一个单独的div中打开它。我已经用一个表单实现了这个功能。但是,我不确定如何传递参数给被调用的javascript函数。我认为我可以将id传递给我的view_article.js.erb文件,然后从那里调用。

@article = Article.find_by_id(id)

然后

<p><%= @article.text %></p>

然而,我不知道如何向这个文件传递任何参数。它可能不起作用,我在做这件事情上可能是完全错误的。正如我所说,我还在学习中。无论如何,感谢您的帮助!


我想我明白你在问什么。你可以尝试在标题元素上设置一个包含文章ID的"data-id"属性,在JS中,你会将click事件绑定到这些标题元素上,提取ID,并向你的文章终端点发起AJAX请求并返回JSON数据,然后在你的div中进行渲染。让我知道我是否正确理解了... - Tracy Fu
大致上是没错的。问题在于,我要一次显示多篇文章,它们都是 <class = article>。我能在一个类中设置 data-id 吗?我以前曾经做到过这一点(不是在 Rails 中),通过设置 click 监听器触发 article_view(id),然后使用 AJAX 获取相关数据。我感觉在 Rails 中也应该可以实现…… - NSchulze
抱歉没有表达清楚。data-id是一种自定义的HTML属性,您可以在任何元素上设置它。更多信息请参见此处。基本上,您需要将事件绑定到具有类article的元素,然后使用jQuery从属性中推断出ID。 - Tracy Fu
2个回答

4

我语法可能有点问题,但是以下是我处理它的方法:

HTML

 <div data-id="<%= @article.id %>" class="article"><%= @article.title %></div>

JS

这里有一些帮助你理解JavaScript如何工作的信息:http://guides.rubyonrails.org/asset_pipeline.html。我通常会创建一个包含某个视图所有绑定(和其他方法)的对象。然后在视图中,在底部的document ready块中创建对象的一个实例,并绑定DOM。所有JS代码都将由清单文件(application.js)添加到你在布局中包含它的位置。

app/assets/javascripts/users.js

// Wraps your binding in a document ready function
// Runs as soon as the DOM is loaded
$(function() {
  $('.article').on('click', function() {
    var id = $(this).attr('data-id');
    $.get('articles/' + id, function(data) {
      // Handle the result
      $('.article-window').html(data);
    });
  });
});

app/assets/javascripts/application.js

  // This directive will include all your js files in the javascripts folder
  //= jquery
  //= require_tree .

app/views/layouts/application.html.erb(或者你的布局所在的任何位置)

意思是这个文件是应用程序中的一个布局文件,通常包含网站的共同元素,比如头部、尾部和导航栏等。
  // This adds all your js to the page
  <%= javascript_include_tag "application" %>

Rails Controller

class ArticlesController < ApplicationController
  respond_to :html, :json
  def show
    @article = Article.find(params[:id]
    respond_with do |format|
      format.json { render :json => @article }
    end
  end
end

这很有道理。我唯一不确定的是在哪里放置JS和Rails控制器的内容。 - NSchulze
抱歉,如果这是一个愚蠢的问题。目前来说,“show”是JavaScript能够工作的唯一地方吗? - NSchulze
如果你只想让它在展示页面上工作,你可以将上面的JS代码从users.js中直接移动到show视图的底部一个script标签中。这样它就只会在该页面上运行。如果你需要它在某些地方运行而在其他地方不运行,请告诉我,我们可以一起解决。 - Tracy Fu
我对respond_with do |format|更加困惑...它是在def show下面吗,因为我正在使用它吗? - NSchulze
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/13196/discussion-between-nschulze-and-tracy-fu - NSchulze
显示剩余2条评论

0
class ArticleController

def show
  @article = Article.find(params[:id]
  respond_to do |format|
    format.json {render :json => @article.text } #now when u try to get host/articles.json/[id of article] you will get json with article object
  end
end

在 article.js.erb 文件中(以我的示例为例,是咖啡文件),你可以使用 http://js2coffee.org/ 将咖啡转换为 js。 article.js.coffee
$('document').ready ->
  $('.article').live 'click', ->
    $.ajax
      url: 'articles/' + $(this).attr('id') #getting article#show with id of article
      complete: (data) ->
        article = JSON.parse(data.responseText)
        $('p').empty()
        $('p').append(article.text)

类似这样的内容 如果您遇到错误,请发送电子邮件至antique@gmail.com


如果我将 ArticleController 中的代码放入不同的控制器中,它仍然会调用 article.js.erb 文件吗? - NSchulze
@antiqe 提醒一下,live()1.7版本中已被弃用,建议使用on() - Tracy Fu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接