Ruby on Rails - 添加太多项目时,jQuery 拖放排序顺序会被丢弃
我正在通过 jQuery UI 构建一个拖放列表,用户可以在其中拖动项目(类别)列表,并且一旦拖动项目,整个事物就会被序列化并传递给控制器作为参数/params[:category] 来索引每个项目并更新其位置。为了尽可能地简化它以尝试找出以下错误,我现在实际上是在 javascript 中手动设置字符串。 (我的 javascript、视图和控制器代码位于下面这篇文章的末尾)。
问题就在这里。对于最多五个项目,它的效果非常好。控制台输出...
Started POST "/categories/sort" for 127.0.0.1 at Wed May 11 12:03:04 -0500 2011
Processing by CategoriesController#sort as
Parameters: {"category"=>{"1"=>{"id"=>"1"}, "2"=>{"id"=>"2"}, "3"=>{"id"=>"3"}, "4"=>{"id"=>"4"}, "5"=>{"id"=>"5"}}}
Category Load (0.3ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = 1 LIMIT 1
AREL (0.5ms) UPDATE "categories" SET "position" = 1, "updated_at" = '2011-05-11 17:03:04.412058' WHERE "categories"."id" = 1
Category Load (0.3ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = 2 LIMIT 1
AREL (0.4ms) UPDATE "categories" SET "position" = 2, "updated_at" = '2011-05-11 17:03:04.416833' WHERE "categories"."id" = 2
[...]
但是,由于某些绝对疯狂的原因,向该字符串添加第六个项目/类别,结果突然变成这样...
Started POST "/categories/sort" for 127.0.0.1 at Wed May 11 12:12:35 -0500 2011
Processing by CategoriesController#sort as
Parameters: {"category"=>{"6"=>{"id"=>"6"}, "1"=>{"id"=>"1"}, "2"=>{"id"=>"2"}, "3"=>{"id"=>"3"}, "4"=>{"id"=>"4"}, "5"=>{"id"=>"5"}}}
Category Load (0.2ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = 6 LIMIT 1
AREL (0.4ms) UPDATE "categories" SET "position" = 1, "updated_at" = '2011-05-11 17:12:35.358963' WHERE "categories"."id" = 6
Category Load (0.2ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = 1 LIMIT 1
AREL (0.2ms) UPDATE "categories" SET "position" = 2, "updated_at" = '2011-05-11 17:12:35.362330' WHERE "categories"."id" = 1
Category Load (0.1ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = 2 LIMIT 1
[...]
如您所见,当添加第六个类别时,该类别的参数用完并成为列表中第一个循环索引的项目,完全失去了正确的顺序。更疯狂的是,如果我在参数字符串中保留“category[6][id]=6”部分并删除前面的一些部分,则无论如何,数字 6 始终是第一个。
这绝对没有意义,我唯一能想到的是我没有正确格式化 javascript 中的参数字符串。我做错了什么?
index.html.erb
<ul id="categories">
<li id="category_1"><div class="handle"></div>One</li>
<li id="category_2"><div class="handle"></div>Two</li>
<li id="category_3"><div class="handle"></div>Three</li>
<li id="category_3"><div class="handle"></div>Four</li>
<li id="category_3"><div class="handle"></div>Five</li>
<li id="category_3"><div class="handle"></div>Six</li>
</ul>
application.js
$("#categories").sortable({
opacity: 0.6,
handle: '.handle',
update: function(event, ui) {
var parameters = 'category[1][id]=1&category[2][id]=2&category[3][id]=3&category[4][id]=4&category[5][id]=5&category[6][id]=6';
$.post("/categories/sort", parameters);
}
});
categories_controller.rb
def sort
params[:category].each_with_index do |id, index|
category_id = id[1][:id]
Category.update(category_id, :position => index + 1)
end
render :nothing => true
end
I'm building a drag-and-drop list via jQuery UI where users can drag a list of items (categories), and as soon as an item is dragged, the whole thing is serialized and passed to the 'sort' function in the controller as the parameters/params[:category] to index through each item and update it's position. For sake of simplifying this as much as possible to try and hunt the following bug out, I am actually manually setting the string in the javascript for now. (My javascript, view and controller code is at the end of this post below).
Here's the problem. With anything up to five items, it works beautifully. Console outputs...
Started POST "/categories/sort" for 127.0.0.1 at Wed May 11 12:03:04 -0500 2011
Processing by CategoriesController#sort as
Parameters: {"category"=>{"1"=>{"id"=>"1"}, "2"=>{"id"=>"2"}, "3"=>{"id"=>"3"}, "4"=>{"id"=>"4"}, "5"=>{"id"=>"5"}}}
Category Load (0.3ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = 1 LIMIT 1
AREL (0.5ms) UPDATE "categories" SET "position" = 1, "updated_at" = '2011-05-11 17:03:04.412058' WHERE "categories"."id" = 1
Category Load (0.3ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = 2 LIMIT 1
AREL (0.4ms) UPDATE "categories" SET "position" = 2, "updated_at" = '2011-05-11 17:03:04.416833' WHERE "categories"."id" = 2
[...]
However for some absolutely crazy reason, add in a sixth item/category to that string, and suddenly the results become this...
Started POST "/categories/sort" for 127.0.0.1 at Wed May 11 12:12:35 -0500 2011
Processing by CategoriesController#sort as
Parameters: {"category"=>{"6"=>{"id"=>"6"}, "1"=>{"id"=>"1"}, "2"=>{"id"=>"2"}, "3"=>{"id"=>"3"}, "4"=>{"id"=>"4"}, "5"=>{"id"=>"5"}}}
Category Load (0.2ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = 6 LIMIT 1
AREL (0.4ms) UPDATE "categories" SET "position" = 1, "updated_at" = '2011-05-11 17:12:35.358963' WHERE "categories"."id" = 6
Category Load (0.2ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = 1 LIMIT 1
AREL (0.2ms) UPDATE "categories" SET "position" = 2, "updated_at" = '2011-05-11 17:12:35.362330' WHERE "categories"."id" = 1
Category Load (0.1ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = 2 LIMIT 1
[...]
As you can see, when adding category number six, the params for that category runs out and becomes the first item in the list to loop through the index with, completely throwing off the correct order. Whats far more crazy is that if I leave the 'category[6][id]=6' portion in the parameters string and eliminate a few before it, number six will always be the first no matter what.
This makes absolutely no sense, and the only thing I can figure is that I'm not formatting the parameters string in the javascript correctly. What am I doing wrong?
index.html.erb
<ul id="categories">
<li id="category_1"><div class="handle"></div>One</li>
<li id="category_2"><div class="handle"></div>Two</li>
<li id="category_3"><div class="handle"></div>Three</li>
<li id="category_3"><div class="handle"></div>Four</li>
<li id="category_3"><div class="handle"></div>Five</li>
<li id="category_3"><div class="handle"></div>Six</li>
</ul>
application.js
$("#categories").sortable({
opacity: 0.6,
handle: '.handle',
update: function(event, ui) {
var parameters = 'category[1][id]=1&category[2][id]=2&category[3][id]=3&category[4][id]=4&category[5][id]=5&category[6][id]=6';
$.post("/categories/sort", parameters);
}
});
categories_controller.rb
def sort
params[:category].each_with_index do |id, index|
category_id = id[1][:id]
Category.update(category_id, :position => index + 1)
end
render :nothing => true
end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我终于能够通过以下线程阐明为什么会发生这种情况: 我的哈希值无序堆叠。可以通过哈希 ID 选择它们的循环是什么?
我正在运行 REE 1.8.7,因此我的参数是没有被排序。我能够通过用此替换排序控制器函数中的each_with_index行来解决问题...
参数在函数内部重新排序,现在以正确的顺序更新数据库。
I was able to finally shed some light on why this was happening via this thread: My hashes are stacking unordered..What's a loop that can select them by their Hash ID?
I am running REE 1.8.7, therefor my param is not being sorted. I was able to solve the issue with replacing the each_with_index line in my sort controller function with this...
The params are resorted inside the function and now update the database in the correct order.