2

正如标题所示,我的主要目标是在 ajax 调用之后呈现动态 scss(.erb) 文件。

资产/javascripts/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

当我单独切换数据库对象时,一切都非常顺利。

现在我想添加一些额外的香料,并li's根据用户当前选择的集合更改我 50+ 的 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 个电话。li's每次调用后,JavaScript 都需要很长时间才能遍历 50 多个。

更新

事实证明,JavaScript 在处理我的“长”列表方面非常快......感谢大家指出我的想法中的错误!

4

3 回答 3

2

在我看来,你遇到的问题与 CSS 无关。这与您的系统如何工作有关

CSS 是静态加载的(来自 http 请求),这意味着当页面呈现时,如果您更改服务器上的 CSS 文件,它将不会更新

JS 是客户端,旨在与呈现的 HTML 元素交互(通过 DOM)。这意味着 JS 本质上是动态的,这就是为什么我们可以将它与 Ajax 等技术一起使用来更改页面的某些部分

这就是我认为您的问题所在...

您的 JS 调用不会重新加载页面,这意味着 CSS 保持静态。目前没有办法重新加载 CSS 并让它们在不刷新的情况下呈现(发送 HTTP 请求)。这意味着您对 JS 所做的任何更新都必须包含每个加载的 CSS

根据对您的 OP 的评论,您应该真正考虑更新列表元素的类。如果你使用这样的东西,它应该可以立即工作:

$('li').addClass('new');

希望这可以帮助?

于 2013-10-18T22:08:16.597 回答
1

如果我正确理解了您的功能,实际上您需要的所有内容都可以通过 JavaScript 简单地实现,无需任何 hack。

让我先整理一下你的特写

  • 给定访问页面的用户
  • 当他选中一个复选框时
  • 他会看到一个加载标志,这意味着这是与服务器的交互
  • 当装载标志停止时
  • 他将看到他检查的行(或“li”)有一个边框,这意味着他的操作已被服务器接受

然后是解决方案。为了便于阅读,我将简化您将符号代码加载到命名函数而不是实际代码中。

$(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*/
      } 
    });
  });
});

让我知道我对功能的理解是否正确以及这是否可以解决问题。

于 2013-10-18T15:13:43.757 回答
0

如果,当用户切换集合选择时,您使用 jquery 更改一个ul,然后基于它定义静态样式怎么办?

例如,您的原始标记可能是:

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- 没有循环遍历lijavascript中的所有 s 并且没有动态加载样式表。

你怎么看,这对你的情况有用吗?

于 2013-10-18T02:00:52.857 回答