正如标题所示,我的主要目标是在ajax调用之后呈现动态scss(.erb)文件。
资产/ Javascript角/ header.js
// onChange of a checkbox, a database boolean field should be toggled via AJAX
$( document ).ready(function() {
$('input[class=collection_cb]').change(function() {
// get the id of the item
var collection_id = $(this).parent().attr("data-collection-id");
// show a loading animation
$("#coll-loading").removeClass("vhidden");
// AJAX call
$.ajax({
type : 'PUT',
url : "/collections/" + collection_id + "/toggle",
success : function() {
// removal of loading animation, a bit delayed, as it would be too fast otherwise
setTimeout(function() {
$("#coll_loading").addClass("vhidden");
}, 300);
},
});
});
});
控制器/ collections_controller.rb
def toggle
# safety measure to check if the user changes his collection
if current_user.id == Collection.find(params[:id]).user_id
collection = Collection.find(params[:id])
# toggle the collection
collection.toggle! :auto_add_item
else
# redirect the user to error page, alert page
end
render :nothing => true
end
当我单独切换数据库对象时,所有工作都非常顺利。
现在我想添加一些额外的香料,并将我的50 + li's
的CSS相应地更改为当前选定的用户集合。
我的所需的CSS 看起来像这样,它检查li元素是否属于集合,如果是,则给它们一个边框颜色。
ul#list > li[data-collections~='8'][data-collections~='2']
{
border-color: #ff2900;
}
我将此添加到我的控制器以生成[]-conditions
:
def toggle
# .
# .
# toggle function
# return the currently selected collection ids in the [data-collections]-format
@active_collections = ""
c_ids = current_user.collections.where(:auto_add_item => true).pluck('collections.id')
if c_ids.size != 0
c_ids.each { |id| @active_collections += "[data-collections~='#{id}']" }
end
# this is what gets retrieved
# @active_collections => [data-collections~='8'][data-collections~='2']
end
现在我需要一种方法将这些括号放在一个动态生成的scss文件中。
我尝试添加:
respond_to do |format|
format.css
end
到我的控制器,文件 views / collections / toggle.css.erb
ul#list<%= raw active_collections %> > li<%= raw active_collections %> {
border-color: #ff2900;
}
它不起作用,另一种方法是从我的控制器渲染css文件,然后将其传递给Manuel Meurer所描述的视图
我弄乱了文件名吗?比如使用css
代替scss
?你有什么想法我应该继续吗?
感谢您的帮助!
为何选择动态CSS? - 推理
我知道这通常应该通过JavaScript添加类来实现。我之所以需要动态css的原因是,当用户决定更改所选集合时,他会非常集中。像3次呼叫4次,然后暂停5分钟,4秒钟5次呼叫。每次调用后,JavaScript只需要很长时间就可以循环遍历50+ li's
。
事实证明,JavaScript处理我的“长”列表非常快......谢谢你们指出我的想法中的错误!
答案 0 :(得分:1)
如果我正确理解了您的功能,实际上您只需通过JavaScript即可实现所有功能,无需任何黑客攻击。
让我先介绍一下你的功能
然后是解决方案。 为了便于阅读,我将把您的加载符号代码简化为命名函数而不是实际代码。
$(document).ready(function() {
$('input[class=collection_cb]').change(function() {
// Use a variable to store parent of current scope for using later
var $parent = $(this).parent();
// get the id of the item
var collection_id = $parent.attr("data-collection-id");
show_loading_sign();
// AJAX call
$.ajax({
type : 'PUT',
url : "/collections/" + collection_id + "/toggle",
success : function() {
// This is the effect you need.
$parent.addClass('green_color_border');
},
error: function() {
$parent.addClass('red_color_border');
},
complete: function() {
close_loading_sign(); /*Close the sign no matter success or error*/
}
});
});
});
如果我对功能的理解是正确的,以及这是否可以解决问题,请告诉我。
答案 1 :(得分:1)
在我看来,你遇到的问题与CSS没有关系;它与你的系统如何工作有关
CSS是静态加载的(来自http请求),这意味着当呈现页面时,如果更改服务器上的CSS文件,它将不会更新
JS是客户端,旨在与呈现的HTML元素(通过DOM)进行交互。这意味着JS本质上是动态的,这也是我们可以将它与Ajax等技术一起使用来改变页面部分的原因
这就是我认为你的问题出现的地方......
你的JS调用没有重新加载页面,这意味着CSS保持静态。目前没有办法重新加载CSS并让它们渲染而不刷新(发送HTTP请求)。这意味着您使用JS进行的任何更新都必须包含每个加载的CSS
根据对OP的评论,您应该真正考虑更新列表元素的类。如果你使用这样的东西它应该立即工作:
$('li').addClass('new');
希望这有帮助吗?
答案 2 :(得分:0)
当用户切换集合选择时,如果在ul
上使用jquery更改一个类,然后根据该类定义静态样式,该怎么办?
例如,您的原始标记可能是:
ul#list.no_selection
li.collection8.collection2
li.collection1
你的css会有静态的:
ul.collection1 li.collection1,
ul.collection2 li.collection2,
...
ul.collection8 li.collection8 {
border-color: #ff2900;
}
因此默认情况下,没有边框。但是如果用户选择集合8,那么你的jquery会这样做:
$('ul#list').addClass('collection8')
并且在li
内的collection8
边框 - 没有循环遍历javascript中的所有li
并且没有动态加载样式表。
你怎么看?这会对你的情况有用吗?