問題集の作成・編集をするときに、問題の順番を指定して登録・保存・表示できるようにしましょう
WHY
- 問題集の並び順を動的に更新したい
WHAT
- [x] 要件を列挙
- [ ] 上記を満たすライブラリを調べる
- [ ] ライブラリをサンプルプロジェクトなどで試してみる
- [x] 並び順を変更した後に,DBと連携する方法を調べる
- [ ] 上記の内容を実装
- [x] 例外処理
https://github.com/isaacHagoel/svelte-dnd-action https://svelte.dev/repl/17119a1dc7a2447695ad1ea40027ee54?version=3.42.1
https://reffect.co.jp/svelte/svelte-table-re-order
問題集内の並びに関してはorder属性があり、並び替えのタイミングで番号を振り直すだけで良さそうです。 DBに対して特別な操作は現時点では不要と認識しています。
実装を進めていますが、以下のバグが消えず途方に暮れています。
-
再現手順
- リアクティブなテーブルの行を一つ選択して入れ替える
- 内部的には選択した問題のコピーが発生しており、入れ替えそのものができない
- 選択状態を解除すると、選択していた問題が見かけ上消える(DBには残っているため、リロードをすると表示される) (+ その後、別のテーブルを表示しようとすると、表示がバグっている)
-
確認できているエラー
// See: issues/520 and 595
TypeError: Cannot read properties of undefined (reading 'getBoundingClientRect')
-
考えられる原因
- 同じ問題が一時的とはいえ2つ発生しているので、ライブラリで一意に識別できない
- DNDライブラリを入れた後から、開発環境がとても重くなった気がする?
- リロードが有意に遅くなっている
-
対処方法(いずれも失敗)
- CSSで選択した行を一時的に表示しないようにする
- 選択した問題を一時的に削除して、配置するときに登録
問題集内の入れ替えは、問題の削除で擬似的に対応できることと、上記のバグが消えないためpending状態です。
import { dndzone } from 'svelte-dnd-action';
// テーブルの行を動的に並び替えるために必要
$: workBookTasksForTable = workBookTasksForTable.map((task, index) => ({
...task,
id: index + 1,
}));
function handleReorder(event: CustomEvent) {
const { items } = event.detail;
if (!Array.isArray(items)) {
console.error('items are expected to be an array.');
return;
}
let newWorkBookTasksForTable = items.map((item, index: number) => {
if (!item || typeof item !== 'object') {
console.error('Invalid item format.');
return null;
}
return { ...item, priority: index + 1, id: index + 1 };
});
if (newWorkBookTasksForTable.includes(null)) {
console.error('Error during reorder: One or more items were invalid.');
return;
}
workBookTasksForTable = newWorkBookTasksForTable;
console.log('after: workBookTasksForTable', workBookTasksForTable);
}
<!-- See: -->
<!-- https://github.com/isaacHagoel/svelte-dnd-action -->
<!-- Note: dndzoneは、HTML要素に対して使用されることを前提としているため、TableBodyのようなコンポーネントは利用できない -->
<tbody
use:dndzone={{ items: workBookTasksForTable, flipDurationMs: 300 }}
on:consider={handleReorder}
on:finalize={handleReorder}
class="divide-y"
>
</tbody>
他のライブラリも試してみましょう
https://sortablejs.github.io/Sortable/#simple-list
https://github.com/tarb/svelte-dnd-list
仕様を変更: 問題の追加順を指定できるようにし、実装のコストを少しだけ低減
Solved by #1174