【问题标题】:how to render a partial by passing an id through jQuery?如何通过 jQuery 传递一个 id 来渲染一个部分?
【发布时间】:2016-05-17 11:25:18
【问题描述】:

我感到非常愚蠢和羞愧。刚开始学习jQuery,第一天就卡住了。基本上,我正在用 ruby​​ on rails 构建所有这些,并且我有一个客户列表,其中包含姓名、地址、电话号码等基本信息。下图中是我的页面布局(是的,我知道.. 天生的艺术家)。

在左表中,我显示了我在数据库中拥有的所有客户,第一列代表客户的 ID,第二列显示他们的名称。在右表(它是部分表)中,我显示了完整的客户信息。 我的目标是:通过点击左侧表格中的行,右侧表格将更新并显示与我选择的客户相关的信息。 这是我尝试过的

<script>
$('#table_clients tbody').on('click', 'tr', function() {
   $("#container_info").replaceWith(
      '<%= j render :partial  => "client_info", :locals =>  {:client => 1} %>'
   );
});
</script>

请注意,我手动指定了客户端的 ID。 我的问题是,如何识别我选择的行并将 ID 传递给 erb 片段?

我可以通过调用这个来获取 ID:

$(this).find(':nth-child(0)').text();

但不知道如何在 erb 片段中传递它。解决这个问题的方法是什么? 可能有比使用 replaceWith 方法更好的方法,这是我得到的第一个想法。

【问题讨论】:

  • 在你的 tr 或类中添加一个data-* 标签,其中将包含客户端的 id(假设你的表是从 db 生成的),所以你可以参考它。跨度>
  • 好的。我熟悉 data-* 标签。但是想象一下,对于每一行,我都有它。 (data-client_1、data-client_2、data-client_3 等。)然后呢?如何将 id 传递给部分?抱歉,我一定看不清楚。
  • 我的建议是,对于每一行(trli 等)添加 data-id=$row_id(来自 php 侧) ,然后单击将其读回为var client_id = $(this).data('id');。也许我没有给出好的建议..
  • 这是一个明智的建议,真的。我什至可能会实现这一点。但是从 Rails 方面来看,我不确定如何传递该 ID。获取 ID 很容易,我有我的方式和你的方式(谢谢),但不知道如何将它传递给 erb 的东西。
  • Ruby 方面,你完全了解了我,我对此一无所知。对不起。

标签: javascript jquery ruby-on-rails ajax


【解决方案1】:

一种解决方案是向后端发出 ajax 请求以获取相关部分。

控制器:app/controllers/clients_controller.rb

class ClientsController < ApplicationController
  #
  # GET /clients/:id/info
  #
  def info
    render partial: "client_info", locals: { client: params[:id] }
  end
end

路线:config/routes.rb

resources :clients do
  member do
    get :info
  end
end

查看:app/clients/index.html.erb

<ul>
  <% @clients.each do |client| %>
    <li class="click" data-client-url="<%= info_client_path client.id %>">
      Click me <%= client.id %>
    </li>
  <% end %>
</ul>

<div class="side-panel">
  Waiting for data
</div>

Javascript:app/assets/javascripts/application.js

$(function(){
  $(".click").click(function(){
    $(".side-panel").load($(this).get("client-url"));
  });
});

它将li 元素中的url 加载到侧边栏中。您只需将代码调整到您的控制器和视图即可使其工作。

【讨论】:

  • 嗨。我觉得这可能有效,我现在正在尝试。两件事:我对路由和 REST 协议真的很不好;应该是“client_info_path client.id %>”而不是“info_client_path client.id %>”?
  • @RareFever 呵呵,我不太确定。我总是使用rake routes 来确定存在哪些路线。两个都试试!
  • 我还没有实施您的解决方案。这个时候很牛逼。看起来很简单,但我对 info_client_path 的事情感到困惑。我下周试试!!谢谢。
  • 这有什么令人困惑的地方?
【解决方案2】:

你可以得到点击的tr的第一个td的innerTextvar id = $(e.currentTarget).children().first()[0].innerText;但是你需要像$('#table_clients tbody').on('click', 'tr', function(e) {这样在回调中接受事件

完整的js小提琴:https://jsfiddle.net/dattaproffs/788tkheh/

但我不确定这将如何工作,也许我误解了'&lt;%= j render :partial =&gt; "client_info", :locals =&gt; {:client =&gt; 1} %&gt;' 不是在服务器上呈现的吗?

【讨论】:

  • 当我加载页面时,右表不存在。但是当我单击任何行(左表)时,右表出现没有问题。当然,只显示ID=1的客户信息。
  • 如果您的其余代码正常工作,那么我的更改将获取 id 并通过它。
  • 好的。我查看了您的小提琴示例,通过在 erb 事物中插入 id 变量,我收到错误“找不到具有 'id'=id 的客户端”。它不会将 id 作为数字传递。它传递的是字符串:“id”。我有点困惑,所以我无法解释为什么这不起作用。 ;/
【解决方案3】:

当您开始使用 javascript 时,请避免陷入将 javascript 与您使用的任何服务器端语言混合在一起的诱惑。

您最终会陷入过度复杂的混乱局面,并且对发生的事情感到困惑。这是一个很常见的错误,没有理由感到羞耻。

按照 Oleander 的建议使用 AJAX 是一个不错的选择 - 但另一种设置 滑块选项卡 的经典方法是使用 ancor 链接。

首先让我们设置表格:

<table id="table_clients">
  <thead>
   <tr>
     <td>id</td>
     <td>name</td>
   </tr>
  </thead>
  <tbody>
    <%= clients.each do |client| %>
      <tr>
        <td>
          <%= client.id %>
        </td>
        <td>
          <%= content_tag :a, client.name, href: "client-<%= client.id %>" %>
        </td>
      </tr>
    <% end %>
  </tbody>
</table>

注意&lt;%= content_tag :a, client.name, href: "client-&lt;%= client.id %&gt;" %&gt; 部分。这将呈现如下内容:

<a href="#client-1">Acme Corp.</a>

所以让我们在右侧创建详细信息:

<% if clients.any %>
<ul id="client-details">
  <%= clients.each do |client| %>
  <li id="client-<%= client-id %>">
    <%= client.details # or whatever %>
  </li>
  <% end %>
</ul>
<% end %>

即使没有 javascript,浏览器现在也会跳到链接的选项卡。进步!

现在让我们用 javascript 增强行为:

// hide everything but the first
$('#client-details li').not(':first').hide();

$('#table_clients').on('click', 'tr,a', function() {
  var id, target;

  // we don't know if the user clicked a link or a row
  if (this.tagName === 'A') {
    id = this.href;
  } else {
    id = $(this).find('a').attr('href'); 
  }

  // since the href is equal to the id we can use it as a selector
  target = $(id);
  target.show(); // show the target
  $('#client-details li').not(target).hide(); // hide the others
  return false; // prevents the view from jumping if the user clicked a link
});

请注意,this 是 javascript 中的一个特殊关键字,它会根据概念改变含义。当您附加单击处理程序时,它是用户单击的元素。 $(this) 为我们提供了一个以该元素为上下文的新 jQuery 对象。

【讨论】:

  • 啊,我明白了。隐藏所有内容,但只显示一个。这就是我所说的好思想。我相信每个循环,而不是“client.id”应该是“c.id”。几个问题:在“this.tagName === 'A'”中,为什么要使用三等号?为什么是大写的“A”?
  • === 是 javascript 严格等于。这意味着只有"A" 是等于“A”的字符串。否则 javascript 会做一些非常疯狂的类型转换。在这种情况下,这并不重要,但使用=== 是一个好习惯
  • 为什么“A”是大写的?因为 DOM 中元素的 tagName 属性是大写的。不要问我为什么。我认为这是因为在 90 年代用 ALLCAPS 编写 HTML 很酷。
  • "client.id" 应该是 "c.id" - 是的,我在那里滑倒了。已编辑
猜你喜欢
  • 1970-01-01
  • 2018-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多