Rails表单内嵌SortableJS时如何更新所有拖拽元素的position隐藏字段
解决方案
你只需要在Sortable的onEnd回调里遍历当前组内所有嵌套表单项,按当前顺序给每个隐藏的position字段赋值即可,适配acts_as_list默认从1开始计数的规则,修改后的代码如下:
1. 更新drag_controller.js逻辑
// javascript/controllers/drag_controller.js connect() { this.sortable = Sortable.create(this.element, { animation: 150, onEnd: this.end.bind(this) }) } end(event) { // 遍历容器内所有嵌套表单项,按当前顺序更新position this.element.querySelectorAll('.nested-fields').forEach((nestedItem, index) => { // 匹配嵌套字段带前缀的position隐藏输入框,不用关心嵌套前缀自动适配 const positionInput = nestedItem.querySelector('input[name*="position"]') if (positionInput) { // acts_as_list默认从1开始计数,所以索引+1,从0计数可直接赋值index positionInput.value = index + 1 } }) }
2. 后端强参数配置确认
确保你的控制器强参数中已经允许position字段传入,嵌套属性配置示例:
# 对应父对象的控制器参数方法,根据你的实际业务调整字段名即可 def parent_model_params params.require(:parent_model).permit( :其他基础字段, items_attributes: [:id, :name, :position, :_destroy] ) end
额外说明
- 如果你使用
cocoon、stimulus-nested-form等支持动态增删嵌套项的工具,上述逻辑依然生效,每次拖拽会自动遍历当前容器内的所有现有项 - 编辑页加载时Rails会自动填充初始position值,不需要额外处理初始化逻辑
内容的提问来源于stack exchange,提问作者Kobius
相关产品推荐
相关产品推荐

