Rails:如何仅在 bootstrap 手风琴打开时从数据库动态加载它
Rails: How can I dynamically load from db into a bootstrap accordion only if it opens
我正在使用
Awesome Nested Set gem 现在创建一个层次结构 我想显示这个层次结构。
我有一个包含典型控制器操作的索引页
klasses_controller.rb
def index
@klasses = Klass.where(depth: 0).order('lft ASC')
end
klasses/index.rb
<div id="accordion" role="tablist" aria-multiselectable="true">
<% @klasses.each do |klass| %>
<%= render :partial => "klass", locals: {klass: klass} %>
<% end %>
</div>
在我的索引操作中,我调用了一个部分
klasses/_klass.html.erb
<div class="klass">
<div class="klass-header" role="tab" id="heading-<%=klass.id%>">
<h5 class="mb-0">
<a data-toggle="collapse"
data-parent="#accordion"
href="#collapse-<%=klass.id%>"
aria-expanded="false"
aria-controls="collapse-<%=klass.id%>">
<%= klass.symbol + " : " + klass.title%>
</a>
</h5>
</div>
<div id="collapse-<%=klass.id%>"
class="collapse"
role="tabpanel"
aria-labelledby="heading-<%=klass.id%>">
<div class="klass-block">
<Here is where I want to render partial for each child>
</div>
</div>
</div>
这是标准的手风琴,可以按原样工作。这是我有一个非常大的数据库的问题,我不想渲染任何不必要的东西。我想等到 header 被单击,然后异步检索我单击的 class 的 children,并使用相同的部分渲染每个。
我怎样才能做到这一点?有没有办法使用 route/controller 动作组合,或者我应该开始写 coffee/java-script?我并不是要重新发明轮子,所以如果有人知道一个例子,那将是受欢迎的。
这是一个棘手的问题,只是因为有很多活动部件。这真是一个令人头疼的问题,但事后看来它非常简单。
首先,我想使用自定义控制器操作,因此我为我的 "children" 方法添加了一条路由,该方法设置为接收 ajax 调用。
routes.rb
get 'klasses/:id/children', to: 'klasses#children', as: 'children_of'
klasses_controller.rb
def index
@klasses = Klass.where(depth: 0).order('lft ASC')
end
def children
respond_to do |format|
format.js {render 'children', :klass => @klass }
end
end
此响应块需要 children.js.erb 调用。
children.js.erb
$("#collapse-<%=@klass.id%>").html("<%= escape_javascript(render :partial => 'klasses/children', locals: { :klass => @klass })%>");
这是我们指定要插入新内容的 div 的地方,我们称之为另一个部分。
_children.html.erb
<div class="child-block">
<% children = @klass.children %>
<% children.each do |child| %>
<%= render :partial => 'klasses/klass', locals: { :klass => child } %>
<% end %>
</div>
最后我重写了我的 _klass.html.erb 部分所以它在标题中有一个 link 将触发 bootstrap 的手风琴 js 并调用我们的新控制器动作。
_klass.html.erb
<div class="klass">
<div class="klass-header" role="tab" id="heading-<%=klass.id%>">
<h5 class="mb-0">
<%= link_to klass.symbol + " : " + klass.title,
children_of_path(klass.id),
remote: true,
:data => { :toggle => "collapse",
:parent => "#accordion",
:target => "#collapse-#{klass.id}"
},
:aria => { :expanded => "false",
:controls => "collapse-#{klass.id}"
}%>
</h5>
</div>
<div id="collapse-<%=klass.id%>"
class="collapse"
role="tabpanel"
aria-labelledby="heading-<%=klass.id%>">
</div>
</div>
差不多就这些了。在 child-block 中添加一些填充,您将拥有一个漂亮的缩进层次结构,可以动态加载内容。
我确实必须为我的控制器中的自定义操作禁用跨站点请求伪造
protect_from_forgery :except => :children
如果有人知道解决方法,请告诉我。
我正在使用 Awesome Nested Set gem 现在创建一个层次结构 我想显示这个层次结构。
我有一个包含典型控制器操作的索引页
klasses_controller.rb
def index
@klasses = Klass.where(depth: 0).order('lft ASC')
end
klasses/index.rb
<div id="accordion" role="tablist" aria-multiselectable="true">
<% @klasses.each do |klass| %>
<%= render :partial => "klass", locals: {klass: klass} %>
<% end %>
</div>
在我的索引操作中,我调用了一个部分
klasses/_klass.html.erb
<div class="klass">
<div class="klass-header" role="tab" id="heading-<%=klass.id%>">
<h5 class="mb-0">
<a data-toggle="collapse"
data-parent="#accordion"
href="#collapse-<%=klass.id%>"
aria-expanded="false"
aria-controls="collapse-<%=klass.id%>">
<%= klass.symbol + " : " + klass.title%>
</a>
</h5>
</div>
<div id="collapse-<%=klass.id%>"
class="collapse"
role="tabpanel"
aria-labelledby="heading-<%=klass.id%>">
<div class="klass-block">
<Here is where I want to render partial for each child>
</div>
</div>
</div>
这是标准的手风琴,可以按原样工作。这是我有一个非常大的数据库的问题,我不想渲染任何不必要的东西。我想等到 header 被单击,然后异步检索我单击的 class 的 children,并使用相同的部分渲染每个。
我怎样才能做到这一点?有没有办法使用 route/controller 动作组合,或者我应该开始写 coffee/java-script?我并不是要重新发明轮子,所以如果有人知道一个例子,那将是受欢迎的。
这是一个棘手的问题,只是因为有很多活动部件。这真是一个令人头疼的问题,但事后看来它非常简单。
首先,我想使用自定义控制器操作,因此我为我的 "children" 方法添加了一条路由,该方法设置为接收 ajax 调用。
routes.rb
get 'klasses/:id/children', to: 'klasses#children', as: 'children_of'
klasses_controller.rb
def index
@klasses = Klass.where(depth: 0).order('lft ASC')
end
def children
respond_to do |format|
format.js {render 'children', :klass => @klass }
end
end
此响应块需要 children.js.erb 调用。
children.js.erb
$("#collapse-<%=@klass.id%>").html("<%= escape_javascript(render :partial => 'klasses/children', locals: { :klass => @klass })%>");
这是我们指定要插入新内容的 div 的地方,我们称之为另一个部分。
_children.html.erb
<div class="child-block">
<% children = @klass.children %>
<% children.each do |child| %>
<%= render :partial => 'klasses/klass', locals: { :klass => child } %>
<% end %>
</div>
最后我重写了我的 _klass.html.erb 部分所以它在标题中有一个 link 将触发 bootstrap 的手风琴 js 并调用我们的新控制器动作。
_klass.html.erb
<div class="klass">
<div class="klass-header" role="tab" id="heading-<%=klass.id%>">
<h5 class="mb-0">
<%= link_to klass.symbol + " : " + klass.title,
children_of_path(klass.id),
remote: true,
:data => { :toggle => "collapse",
:parent => "#accordion",
:target => "#collapse-#{klass.id}"
},
:aria => { :expanded => "false",
:controls => "collapse-#{klass.id}"
}%>
</h5>
</div>
<div id="collapse-<%=klass.id%>"
class="collapse"
role="tabpanel"
aria-labelledby="heading-<%=klass.id%>">
</div>
</div>
差不多就这些了。在 child-block 中添加一些填充,您将拥有一个漂亮的缩进层次结构,可以动态加载内容。
我确实必须为我的控制器中的自定义操作禁用跨站点请求伪造
protect_from_forgery :except => :children
如果有人知道解决方法,请告诉我。