Table 使用索引分配排序
Table sorting with index assignment
我有 array
个对象:
ruta: [
{ 'order': 1, 'id': 121 },
{ 'order': 2, 'id': 123 }
]
我用它作为 buefy table and at the same time, I'm using the extension sortable.js 的模型来手动排序 table 行:
const createSortable = (el, options, vnode) => {
return Sortable.create(el, {
...options,
onEnd: function (evt) {
const data = vnode.context.ruta
const item = data[evt.oldIndex]
if (evt.newIndex > evt.oldIndex) {
for (let i = evt.oldIndex; i < evt.newIndex; i++) {
data[i] = data[i + 1]
}
} else {
for (let i = evt.oldIndex; i > evt.newIndex; i--) {
data[i] = data[i - 1]
}
}
data[evt.newIndex] = item
//here
for (let i = 0; i < data.length; i++) {
data[i].order = i + 1;
}
}
})
}
table 已正确呈现,但我需要在每次手动排序时更新 order
参数以反映 table 的真实顺序。例如,我需要将第五行移动到 table 的开头,因此其 order
参数应为 1,其余行需要反映 2、3、4 和 5。
如您在代码中所见,我已尝试:
for (let i = 0; i < data.length; i++) {
data[i].order = i + 1;
}
因为我要从1的值开始排序。我还尝试将更改放入 if / else
块中:
if
data[i].order = i + 1;
else
data[i].order = i - 1;
但是也没用。以错误的方式更改了行的顺序。
你已经在 the Spanish SO site 上问过这个问题,我在那里给了你一个解决方案。我知道您已经解决了这个问题,但我将 post 为您的问题提供另一个解决方案,因为将来它可能对其他用户有用。
首先,我已经向你解释了为什么会出现这个问题:如果你改变模型的顺序改变它的索引值,Vue
will not detect the change,你需要修改array
以另一种方式,例如,制作 splice
。在您的代码中,Vue
仅在您更改 order
参数时检测到更改,此时列表是手动排序的,并且 array
的每个索引的值都已更改,因此,视图会被错误更新:
┌───────────────┬───────────────┬──────────────────┬───────────────┐
│ Initial state │ -> Model │ Manually sorting │ -> Model │
├───────────────┼───────────────┼──────────────────┼───────────────┤
│ 1 - item 1 │ Array index 0 │ 1 - item 4 │ Array index 3 │
│ 2 - item 2 │ Array index 1 │ 2 - item 1 │ Array index 0 │
│ 3 - item 3 │ Array index 2 │ 3 - item 2 │ Array index 1 │
│ 4 - item 4 │ Array index 3 │ 4 - item 3 │ Array index 2 │
└───────────────┴───────────────┴──────────────────┴───────────────┘
之前给大家的解决方案:
const createSortable = (el, options, vnode) => {
// Copy the order property
vnode.context.data.forEach( (obj) => {obj.norder = obj.order} );
// Create an array of orders
const orders = vnode.context.data.map((obj) => obj.order);
return Sortable.create(el, {
...options,
onEnd: function (evt) {
const data = vnode.context.data;
// Update the position of the objects
orders.splice(evt.newIndex, 0, ...orders.splice(evt.oldIndex, 1));
// Change the order parameter
data.forEach((obj) => {
obj.order = orders.findIndex((n) => n === obj.norder) + 1;
});
}
});
};
工作示例:https://codepen.io/elchininet/pen/JLQqEV
另一种解法:
另一个解决方案是在每次移动后重置手动排序并使用 splice
更改 array
顺序。看看:
const createSortable = (el, options, vnode) => {
let order = [];
return Sortable.create(el, {
...options,
onStart: function (evt) {
// when the sort starts, store the initial order of the array
order = this.toArray();
},
onEnd: function (evt) {
// when the sort ends, set the order to the initial state
this.sort(order);
// change the order using splice
const data = vnode.context.data;
data.splice(evt.newIndex, 0, ...data.splice(evt.oldIndex, 1));
// now it is safe, you can update the order parameter
data.forEach((o, i) => {
o.order = i + 1;
});
}
});
};
这里有一个工作示例:https://codepen.io/elchininet/pen/MVNaON
我有 array
个对象:
ruta: [
{ 'order': 1, 'id': 121 },
{ 'order': 2, 'id': 123 }
]
我用它作为 buefy table and at the same time, I'm using the extension sortable.js 的模型来手动排序 table 行:
const createSortable = (el, options, vnode) => {
return Sortable.create(el, {
...options,
onEnd: function (evt) {
const data = vnode.context.ruta
const item = data[evt.oldIndex]
if (evt.newIndex > evt.oldIndex) {
for (let i = evt.oldIndex; i < evt.newIndex; i++) {
data[i] = data[i + 1]
}
} else {
for (let i = evt.oldIndex; i > evt.newIndex; i--) {
data[i] = data[i - 1]
}
}
data[evt.newIndex] = item
//here
for (let i = 0; i < data.length; i++) {
data[i].order = i + 1;
}
}
})
}
table 已正确呈现,但我需要在每次手动排序时更新 order
参数以反映 table 的真实顺序。例如,我需要将第五行移动到 table 的开头,因此其 order
参数应为 1,其余行需要反映 2、3、4 和 5。
如您在代码中所见,我已尝试:
for (let i = 0; i < data.length; i++) {
data[i].order = i + 1;
}
因为我要从1的值开始排序。我还尝试将更改放入 if / else
块中:
if
data[i].order = i + 1;
else
data[i].order = i - 1;
但是也没用。以错误的方式更改了行的顺序。
你已经在 the Spanish SO site 上问过这个问题,我在那里给了你一个解决方案。我知道您已经解决了这个问题,但我将 post 为您的问题提供另一个解决方案,因为将来它可能对其他用户有用。
首先,我已经向你解释了为什么会出现这个问题:如果你改变模型的顺序改变它的索引值,Vue
will not detect the change,你需要修改array
以另一种方式,例如,制作 splice
。在您的代码中,Vue
仅在您更改 order
参数时检测到更改,此时列表是手动排序的,并且 array
的每个索引的值都已更改,因此,视图会被错误更新:
┌───────────────┬───────────────┬──────────────────┬───────────────┐
│ Initial state │ -> Model │ Manually sorting │ -> Model │
├───────────────┼───────────────┼──────────────────┼───────────────┤
│ 1 - item 1 │ Array index 0 │ 1 - item 4 │ Array index 3 │
│ 2 - item 2 │ Array index 1 │ 2 - item 1 │ Array index 0 │
│ 3 - item 3 │ Array index 2 │ 3 - item 2 │ Array index 1 │
│ 4 - item 4 │ Array index 3 │ 4 - item 3 │ Array index 2 │
└───────────────┴───────────────┴──────────────────┴───────────────┘
之前给大家的解决方案:
const createSortable = (el, options, vnode) => {
// Copy the order property
vnode.context.data.forEach( (obj) => {obj.norder = obj.order} );
// Create an array of orders
const orders = vnode.context.data.map((obj) => obj.order);
return Sortable.create(el, {
...options,
onEnd: function (evt) {
const data = vnode.context.data;
// Update the position of the objects
orders.splice(evt.newIndex, 0, ...orders.splice(evt.oldIndex, 1));
// Change the order parameter
data.forEach((obj) => {
obj.order = orders.findIndex((n) => n === obj.norder) + 1;
});
}
});
};
工作示例:https://codepen.io/elchininet/pen/JLQqEV
另一种解法:
另一个解决方案是在每次移动后重置手动排序并使用 splice
更改 array
顺序。看看:
const createSortable = (el, options, vnode) => {
let order = [];
return Sortable.create(el, {
...options,
onStart: function (evt) {
// when the sort starts, store the initial order of the array
order = this.toArray();
},
onEnd: function (evt) {
// when the sort ends, set the order to the initial state
this.sort(order);
// change the order using splice
const data = vnode.context.data;
data.splice(evt.newIndex, 0, ...data.splice(evt.oldIndex, 1));
// now it is safe, you can update the order parameter
data.forEach((o, i) => {
o.order = i + 1;
});
}
});
};
这里有一个工作示例:https://codepen.io/elchininet/pen/MVNaON