2017-07-01 11 views
3

私は、プロジェクトを使用するvuexを使用するアプリケーションで作業しています。各プロジェクトには1つ以上のジョブがあります。配列内の項目を更新すると、すべてが更新されます

ジョブを追加、削除、更新できます。追加と削除は完全に機能していますが、更新はできません。

vuex devのツールでの状態:

projects

マイHTML:

<div class="job-compact row" v-for="(job, index) in project.jobs"> 
     <div class="col-md-6"> 
      <div class="form-group" :class="{'has-error' : errors.has('jobs.' + index + '.function')}"> 
       <input type="text" name="jobs[function][]" class="form-control" v-model="job.function" @change="updateJobValue(index, 'function', $event.target.value)"/> 
      </div> 
     </div> 
     <div class="col-md-4"> 
      <div class="form-group" :class="{'has-error' : errors.has('jobs.' + index + '.profiles')}"> 
       <input type="number" name="jobs[profiles][]" class="form-control" v-model="job.profiles" @change="updateJobValue(index, 'profiles', $event.target.value)"/> 
      </div> 
     </div> 
     <div class="col-md-2"> 
      <button v-if="index == 0" class="btn btn-success btn-sm" @click="addJob"><i class="fa fa-plus"></i></button> 
      <button v-if="index > 0" class="btn btn-danger btn-sm" @click="deleteJob(index);"><i class="fa fa-minus"></i></button> 
     </div> 
    </div> 

あなたが見ることができるように、私はすべての私の仕事を見せているv-forを持っています。私の仕事の中で値を編集するとき、私は@changeイベントを使って自分の値を更新します。そして、下部には、ジョブ行を追加および削除する2つのボタンがあります。

enter image description here

私の店はモジュールに分割されています。主な店舗は、次のようになります。

import Vue from 'vue' 
import Vuex from 'vuex' 

Vue.use(Vuex); 

const state = {}; 

const getters = {}; 

const mutations = {}; 

const actions = {}; 

//Separate Module States 
import jobCreator from './modules/job-creator/store'; 

export default new Vuex.Store({ 
    modules: { 
     jobCreator: jobCreator 
    }, 
    state, 
    actions, 
    mutations, 
    getters 
}); 

この特定の問題のためのモジュールストア:

computed: { 
     ...mapState({ 
      project: state => state.jobCreator.project, 
     }), 
} 

import store from './../../store' 

const state = { 
    project: { 
     title: null, 
     description: null, 
     jobs: [] 
    }, 
    defaultJob: { 
     function: '', 
     title: '', 
     description: '', 
     profiles: 1, 
     location_id: '', 
     category_id: '', 
     budget: '', 
    }, 
}; 

const getters = {} 

const mutations = { 

    addJob(state, job) { 
     state.project.jobs.push(job); 
    }, 
    deleteJob(state, index) { 
     state.project.jobs.splice(index, 1); 
    }, 
    updateJobValue(state, params) { 
     Object.assign(state.project.jobs[params.jobIndex], { 
      [params.field]: params.value 
     }); 
    } 
}; 

const actions = { 
    addJob: function (context) { 
     context.commit('addJob', state.defaultJob); 
    }, 
    deleteJob: function (context, index) { 
     context.commit('deleteJob', index); 
    }, 
    updateJobValue: function (context, params) { 
     context.commit('updateJobValue', params); 
    }, 
}; 

const module = { 
    state, 
    getters, 
    mutations, 
    actions 
}; 

export default module; 

プロジェクトの状態は私のVUEインスタンスの計算されたプロパティにマッピングされています問題は次のとおりです。アプリケーションのイメージでは、いずれかのフィールドに「vin」と入力したが、すべてのフィールドが更新されていることがわかります。

enter image description here

ので、functionフィールドすべてすべてジョブではなく、私が欲しいだけで、私の最後のエントリに更新されました。

私は間違っていますか?

PS:

私も自分の変異機能で、次を試してみました:

updateJobValue(state, params) { 
    var job = state.project.jobs[params.jobIndex]; 
    job[params.field] = params.value; 

    Vue.set(state.project.jobs, params.jobIndex, job); 
} 

しかし、それは私に同じ結果を与えています。

UPDATE:あなたが結合唯一の方法をしたいので

使用v-bind:value="job.function代わりv-model="job.function"の:要求された、私は次のようなアドバイスを与えるだろう私の問題

+0

おそらくこれをjsfiddleに変換できますか?それはかなり長い質問であるので、人々があなたをその方法で手助けする方がずっと簡単です。 –

+0

私の問題を説明するjsfiddleを追加しました – vincent

答えて

8

問題は、あなたのaddJobアクションである:

addJob: function (context) { 
    context.commit('addJob', state.defaultJob); 
}, 

あなたはstate.defaultJobオブジェクトにあなたが新しい仕事を追加するたびに参照されています。つまり、state.project.jobs配列内の各項目は同じオブジェクトを参照しています。

addJob変異に渡すときには、オブジェクトのコピーを作成する必要があります。

addJob: function (context) { 
    context.commit('addJob', Object.assign({}, state.defaultJob)); 
}, 

それとも、単にデフォルトのプロパティを持つ新しいオブジェクト内の各時間を渡す:

addJob: function (context) { 
    context.commit('addJob', { 
     function: '', 
     title: '', 
     description: '', 
     profiles: 1, 
     location_id: '', 
     category_id: '', 
     budget: '', 
    }); 
}, 

Here's a working fiddle.

ここに、変数がJavascriptでどのように渡されるかを説明する投稿があります:Javascript by reference vs. by value

1

を表示するjsFiddleを作成したよう。このコードはより予測可能です。

レンダリングが正しく動作するようにv-for="(job, index) in project.jobs"要素にv-key="job"を追加してください。

最初の2行は十分なはずですが、オブジェクトはまだ反応しています。

var job = state.project.jobs[params.jobIndex]; 
job[params.field] = params.value; 


Vue.set(state.project.jobs, params.jobIndex, job); 

PS:私は、Enterキーを押すか、入力を去ったときに私のバイオリンで@changeだけ火をしました。

+0

私の問題を説明するjsfiddleを追加しました – vincent

+0

あなたの問題はいつも同じオブジェクトを追加/参照している 'context.commit( 'addJob'、state.defaultJob);' です。 'context.commit( 'addJob'、Vue.extend({}、state.defaultJob))'に変更して、各行に新しいオブジェクトを取得します。 – Reiner

関連する問題