2017-11-28 14 views
0

子コンポーネントから正しいオブジェクトを更新する際に問題があります。Vue.js - 子コンポーネントでパターンを更新または元に戻す

私の設定は以下の通りです: 私が提示したい、または編集したいデータのほとんどが1つのリストです。 "li"の一部には、そのオブジェクトに接続されているリソースのリストであるデータの一部を示す子コンポーネントがあり、新しいリソースのプッシュを処理します。

また、行の有効な編集モードのボタンと、[更新]と[キャンセル]のボタンが必要です。

私が直面している問題は、どのオブジェクトを編集して保存すべきかを理解することです。私が今やっていることは、row内のデータをmutableRowにコピーしようとしていて、入力コントロールのモデルとして使用していますが、ユーザーが編集モードでないときに実際の行データが表示されています。更新メソッドでは、私はdbに投稿し、行オブジェクトを更新しました。

ul 
    li(v-for="row in rows") 
    p(v-if="!row.editing") {{ row.name }} 
    input(v-else, v-model="mutableRow.name") 
    resources(:row="row") 
    button(v-if="!row.editing") Start edit 
    template(v-else) 
     button Update 
     button Cancel 

これは正しい方法ですか、そうなら、子コンポーネントに送信される小道具はどのように処理すればよいですか?私はこれを介してmutableRowをフェッチしようとしました。$ parent.mutableRow、 "リソース(:row =" row ")をv-ifで切り替えようとしましたが、編集モードであればmutableRowを送ります。どのようにコンポーネントから両方のオブジェクトを変更するアップ。

ここで使用できる別のパターンはありますか?

+0

私は全体が '' editing'状態と編集値は、コンポーネントの内部にあると、成分をli'なるだろう。更新はイベントを発行し、キャンセルは編集値をリセットするだけです。 –

+0

私はあなたが意味することを正確に理解していないので、おそらく例を挙げることができますか? :/ 全体を1つのコンポーネントにする必要がありますか?問題は多くの異なる入力フィールドがあるので、メソッドとテンプレートがたくさんあるため、小さな部品にしようとしました。 – Solander

+0

データの表示方法を教えてください。 1つのコンポーネントがその内部に小さなコンポーネントを持つ必要があります。 –

答えて

1

あなたが言及している "可変行"の問題は、rowではなくrows[index]を渡すことで対処されていると思います。いずれにせよ、それは.syncを動作させるために必要なことです。

以下の例では、コメントの中で私が提案した内容を実装しています。データのコピーと編集モードのための独自のコントロールを持つ単一のコンポーネントです。編集を開始すると、小道具データがローカルデータにコピーされます。 「更新」をクリックすると、イベントが発行され、親(syncを介して)が編集されたデータを行にコピーします。キャンセルをクリックすると、イベントは出力されず、編集が終了します。

new Vue({ 
 
    el: '#app', 
 
    data: { 
 
    rows: [{ 
 
     name: "Test", 
 
     thingy: 4, 
 
     resources: [{ 
 
     title: "Title", 
 
     price: 5000 
 
     }] 
 
    }] 
 
    }, 
 
    components: { 
 
    rowEditor: { 
 
     template: '#row-editor-t', 
 
     props: ['row'], 
 
     data() { 
 
     return { 
 
      editing: false, 
 
      localRow: null 
 
     }; 
 
     }, 
 
     methods: { 
 
     startEditing() { 
 
      this.editing = true; 
 
      this.localRow = JSON.parse(JSON.stringify(this.row)); 
 
     }, 
 
     stopEditing() { 
 
      this.editing = false; 
 
     }, 
 
     update() { 
 
      this.$emit('update:row', this.localRow); 
 
      this.stopEditing(); 
 
     }, 
 
     cancel() { 
 
      this.stopEditing(); 
 
     } 
 
     } 
 
    } 
 
    } 
 
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script> 
 
<div id="app"> 
 
    <ul> 
 
    <li v-for="row, index in rows" is="row-editor" :row.sync="rows[index]"> 
 
    </li> 
 
    </ul> 
 
</div> 
 

 
<template id="row-editor-t"> 
 
    <li> 
 
    <div v-if="editing"> 
 
     <input v-model="localRow.name"> 
 
     <div v-for="resource in localRow.resources"> 
 
     <input v-model="resource.title"><input v-model="resource.price"> 
 
     </div> 
 
    </div> 
 
    <div v-else> 
 
     {{row.name}} 
 
     <div v-for="resource in row.resources"> 
 
     {{resource.title}}: {{resource.price}} 
 
     </div> 
 
    </div> 
 
    <div v-if="editing"> 
 
     <button type="button" @click="update">Update</button> 
 
     <button type="button" @click="cancel">Cancel</button> 
 
    </div> 
 
    <button v-else @click="startEditing">Start edit</button> 
 
    </li> 
 
</template> 
 

 
<!-- 
 
ul 
 
    li(v-for=" row in rows ") 
 
    p(v-if="!row.editing ") {{ row.name }} 
 
    input(v-else, v-model="mutableRow.name ") 
 
    resources(:row="row ") 
 
    button(v-if="!row.editing ") Start edit 
 
    template(v-else) 
 
     button Update 
 
     button Cancel 
 
-->

+0

パーフェクト!このソリューションは、コード内の問題を見つけるのに本当に役立ちました。すべての行をコンポーネントに分割し、全体で1つのコンポーネントのみを使用していました。私が見つけたのは、 "this.mutableRow = Vue.util.extend({}、this.row)"がオブジェクトのコピーに使用していただけで、浅いコピーが作成されていたことがわかりました。私は、元のオブジェクトの "リソース"配列を変更し終わった。今は、深いコピーを作成する代わりに、jQuery.extend(true、{}、this.row)を使用しています。トリックが最高ですが、これは動作します。 ありがとう! – Solander

関連する問題