所以我有一个名为_node.html.erb
的部分。在我的应用程序中,它在不同的视图(以及来自不同的控制器)中呈现。在一个特定的视图中,我会生成一个可链接(和唯一)的events
列表。
我想要发生的是,每当有人点击其中一个链接时,它会显示部分并使用正确的信息填充它。我最初尝试这样做的方法是将data-attributes
从链接传递给一些更新部分的JS。当我们到达node.comments
时,这会快速进入隔离墙,其中部分内容应加载与正在呈现的node
相关联的所有评论。
例如,以下是我的_node.html.erb
可能的示例代码:
<!-- Card Meta -->
<div class="card__meta">
<aside>
<%= image_tag node.user.avatar.url, class: "card__author-avatar", alt: "" %>
</aside>
<section>
<h6 class="card__author-name"><%= node.user.name %></h6>
<time class="card__date"><%= node.created_at.strftime("%B %d, %Y") %></time>
<p class="card__description"><%= node.media.try(:description) %>
<textarea class="card-form__description" name="" id="" cols="30" rows="10">Aenean lacinia bibendum nulla sed consectetur.</textarea>
</section>
</div>
<!-- End Card Meta -->
<!-- Card Comments -->
<div class="card-comments-container">
<h4 class="card-comments__title"><%= pluralize(node.comments_count, "Comment") %></h4>
<a class="card-comments__button"><i class="icon-arrow-down"></i></a>
<div class="card-comments">
<%= render partial: "nodes/comment", collection: node.comments.includes(:user).order(created_at: :desc) %>
</div>
</div>
<!-- End Card Comments -->
以下是用户可以按的链接示例,或者更确切地说是生成链接的Rails代码:
<div class="item-wrapper">
<div class="item_comment">
<h5 class="item_comment-title"><%= event.action %> on <%= link_to event.eventable.node.name, "#", data: {toggle_card: "", card_id: event.eventable.node.id, card_title: event.eventable.node.media.title, card_description: event.eventable.node.media.description, card_time: event.eventable.node.media.created_at, card_comments: event.eventable.node.comments_count, card_favorites: event.eventable.node.cached_votes_total } %></h5>
<p class="item_comment-text"><%= event.eventable.message %></p>
</div>
</div>
这是我最初使用的jQuery类型的一个例子:
$(document).ready(function() {
var overlay = $('.card-overlay'),
$card = overlay.find('.card'),
triggers = $('a[data-toggle-card]');
overlay.hide();
overlay.click(function(e) {
if( e.target != this ) {
} else {
overlay.hide();
}
});
triggers.click(function() {
var trigger = $(this);
var tr = trigger;
overlay.show();
var card = {
id: tr.data('card-id'),
title: tr.data('card-title'),
description: tr.data('card-description'),
time: tr.data('card-time'),
comments: tr.data('card-comments'),
favorites: tr.data('card-favorites'),
};
$card.attr('id', 'card-' + card.id);
$card.find('.card__content').attr('style', 'background-image: url(' + card.image + ')');
$card.find('.card__favorite-count').html('<i class="icon-heart"></i> ' + card.favorites);
$card.find('.card__comment-count').html('<i class="icon-speech-bubble-1"></i> ' + card.comments);
$card.find('.card__title').text(card.title);
$card.find('.card__date').text(card.time);
$card.find('.card__description').text(card.description);
$card.find('textarea').attr('id', 'card-input-field-' + card.id);
var player = videojs("example_video_" + card.id, {}, function() {});
player.src(
{
src: card.video.mp4, type: 'video/mp4'
},
{
src: card.video.webm, type: 'video/webm'
},
{
src: card.video.ogv, type: 'video/ogv'
}
);
player.load();
player.ready(function() {
console.log("READY")
});
return false;
});
});
如何在不依赖太多JS / jQuery的情况下以更“Railsy”的方式执行此操作?
修改1
在尝试Rich Peck的建议后,我收到了这个错误:
05:46:31 web.1 | Unexpected error while processing request: JS, accepted HTTP methods are OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK, VERSION-CONTROL, REPORT, CHECKOUT, CHECKIN, UNCHECKOUT, MKWORKSPACE, UPDATE, LABEL, MERGE, BASELINE-CONTROL, MKACTIVITY, ORDERPATCH, ACL, SEARCH, and PATCH
要清楚,这就是我所做的:
修改了我的路线:
resources :events do
get :node, action: :node
end
然后在我的EventsController
中创建了一个名为node
的动作,如下所示:
def node
@node = current_user.nodes.find(params: [node_id])
respond_to do |format|
format.js
end
end
然后我创建了一个app/views/events/node.js.erb
,看起来像这样:
$overlay = $('.card-overlay');
$node = $('<%= j render "nodes/node", locals: {node: @node} %>');
$overlay.append($node);
然后我修改了link_to
标签,如下所示:
<%= link_to event.eventable.node.name, event_node_path(event.eventable.node), remote: true, method: :js %></h5>
答案 0 :(得分:1)
您需要向服务器发出AJAX请求,然后使用js.erb
部分将可能要求的内容返回给前端。这是最多&#39; Rails-y&#39;我能想到的方式。
就个人而言,我要求使用JSON,然后使用一些jQuery来回复返回值,就像在您的示例中所做的那样。通过呼叫后端是你能够获得相关记录的唯一理智方式,.comments
位,我相信你会被困在哪里,如果我有的话理解你的问题。
编辑:
This是关于如何使用Rails实现AJAX-y的相当好的教程,以防你过去没有太多理由这样做。
答案 1 :(得分:1)
好的,这里有两个问题:
你正试图加载&amp;填充部分没有任何额外数据(IE node.comments
)
其次,您非常依赖JQuery
来更新页面上的各种属性。虽然这本身没有任何问题,但如果您想要更改页面布局等, 会成为问题。
执行此操作的更“困难”的方法是直接从服务器远程加载节点,就像推荐Alex Lynham
一样:
#config/routes.rb
resources :cards do
get :node_id, action: :node #-> url.com/cards/:card_id/:node_id
end
#app/controllers/cards_controller.rb
class CardsController < ApplicationController
def node
@card = Card.find params[:card_id]
@node = @card.nodes.find params[:node_id]
respond_to do |format|
format.js #-> app/views/cards/node.js.erb
end
end
end
#app/views/cards/node.js.erb
$node = $("<%=j render "cards/node", locals: {node: @node} %>")
$('body').append($node);
#app/views/cards/index.html.erb
<% @cards.each do |card| %>
<%= link_to card.name, card_node_path(@card), remote: true, format: :js %>
<% end %>
这将使代码清晰简洁。
您可以将所有选项直接放在_node.js.erb
部分中。虽然它仍然意味着你必须做出一些改变,它会让你能够改变你的部分和没有你现在拥有的所有JQuery专业化的实现。