問題についてのベストプラクティス(あるいはゴーする練習)リストとコンポーネントは、データの変更後に更新されない - (VueJS + VueX)
私はリスト(元to-doリストを。)持っています。実際のアプローチは次のとおりです。
私の親コンポーネントでは、私は 'store.todos'配列を作成します。 ゲッターを使用して、すべてのTo-Doを取得し、v-for ループを使用してリストを反復処理します。
すべてのアイテムはコンポーネントであり、私はそのアイテムを支柱として送信します。
このコンポーネントでは、 "done"フラグを更新するロジックがあります。そしてこの要素は、フラグの "状態"に基づいてチェックボックスを表示します。それが実行されると、dbへのアクションが実行され、ストアの状態が更新されます。
代わりに、私必要があります。
- は、各リスト項目ゲッターを持ち、かつ唯一の子コンポーネントの下IDを送信するようにしたことがありますか?
すべてがうまくいきますが、予定リストに新しいアイテムを追加すると、完了したとマークするとこのアイテムは更新されません。私は子コンポーネント内の小道具ではなくゲッターを使用しているため、この問題がある場合、私は疑問に思う
コード:
店舗:
const state = {
tasks: []
}
const mutations = {
CLEAR_TASKS (state) {
state.tasks = [];
},
SET_TASKS (state, tasks) {
state.tasks = tasks;
},
ADD_TASK (state, payload) {
// if the payload has an index, it replaces that object, if not, pushes a new task to the array
if(payload.index){
state.currentSpaceTasks[payload.index] = payload.task;
// (1) Without this two lines, the item doesn't update
state.tasks.push('');
state.tasks.pop();
}
else{
state.tasks.push(payload.task);
}
},
SET_TASK_COMPLETION (state, task){
let index = state.tasks.findIndex(obj => obj.id == task.id);
state.tasks[index].completed_at = task.completed_at;
}
}
const getters = {
(...)
getTasks: (state) => (parentId) => {
if (parentId) {
return state.tasks.filter(task => task.parent_id == parentId);
} else {
return state.tasks.filter(task => !task.parent_id);
}
}
(...)
}
const actions = {
(...)
/*
* Add a new Task
* 1st commit add a Temp Task, second updates the first one with real information (Optimistic UI - or a wannabe version of it)
*/
addTask({ commit, state }, task) {
commit('ADD_TASK',{
task
});
let iNewTask = state.currentSpaceTasks.length - 1;
axios.post('/spaces/'+state.route.params.spaceId+'/tasks',task).then(
response => {
let newTask = response.data;
commit('ADD_TASK',{
task: newTask,
index: iNewTask
});
},
error => {
alert(error.response.data);
});
},
markTaskCompleted({ commit, dispatch, state }, task){
console.log(task.completed_at);
commit('SET_TASK_COMPLETION', task);
dispatch('updateTask', { id: task.id, field: 'completed', value: task.completed_at }).then(
response => {
commit('SET_TASK_COMPLETION', response.data);
},
error => {
task.completed_at = !task.completed_at;
commit('SET_TASK_COMPLETION', task);
});
},
updateTask({ commit, state }, data) {
return new Promise((resolve, reject) => {
axios.patch('/spaces/'+state.route.params.spaceId+'/tasks/'+ data.id, data).then(
response => {
resolve(response.data);
},
error => {
reject(error);
});
})
}
}
そして、基本的に、これは私の親と子のコンポーネントは次のとおりです。
タスクリストコンポーネント(それはゲッターからタスクをロードする) (...)
<task :task = 'item' v-for = "(item, index) in tasks(parentId)" :key = 'item.id"></task>
(...)
タスクコンポーネントは「チェックボックス」(Fontawesomeを使用)を表示します。完了したかどうかに応じて、チェックされているかされていないかがチェックされます。
この手順では正常に動作します:
- アクセスタスクリスト
- マーク1つの既存のアイテムに行わとして - チェックボックスが
をチェックされている。この手順では、
- 新しいタスクを追加に失敗しました(これは、最初に '一時的な'アイテムを追加するaddタスクを起動し、ajaxを返した後、reaで更新しますl情報(イドなど)。 IDを持っていない間、タスクはチェックボックスの代わりに読み込みを表示し、更新後にチェックボックスを表示します - これは機能します!
- 新しく追加されたタスクを確認します。要求を送信し、アイテムとDBを更新します。しかし、チェックボックスは更新されていません:(
ゲッターのデザインは、私は信じて完全にあなた次第です。最後の質問について - 実際のコードなしで言うのは難しいです。おそらく、あなたは 'v-for'要素に一意の' key'属性を割り当てなかったでしょう(更新がテンプレートに反映されていない場合)。 – wostex
@wostex私は今朝これを試していましたが、運が無ければ、公正であるために、最初にコンセプトを得ていないので、正しく実行しませんでした。今夜それをチェックし、それが解決すれば教えてください! –
問題が解決しない場合は、関連するコード部分を質問に追加してください。デバッグに役立ちます。 – wostex