2017-12-20 14 views
0

例オブジェクト:私は2つのレベル(アレイ)とのデータ構造を有するhttps://jsfiddle.net/hxv5bLqt/VueJS 2 - アレイ内部時計の特性および/または問題の

を。第1レベルは「部品」であり、第2レベルは「部品」であり、各「部品」の内側にある。各項目の値の合計値を格納する変数もあります。この例の作業は次のとおりです。ユーザーが値フィールドに何かを入力するか、値を削除するたびに、合計を再計算する必要があります。

しかし、私は "this.recompute()"メソッドを呼び出す必要があるすべての場所をマップする必要があり、ウォッチまたは計算されたプロパティでこれが可能であるため、サンプルソリューションに満足できません。清潔で反応的な方法で解決されました。

しかし、配列内にあるオブジェクトのプロパティの変更を見ることができる「時計」や「計算されたプロパティ」を実装することはできません。 「観る」ケースでは

、私は理想的なことを想像して、私は仕事だろうと思ったことは次のとおりです。

watch: { 
    'parts.X.items.Y.value': function(oldValue, newValue) { 
     this.recompute() 
    } 
} 

「X」と「Y」はフィールドが観察されることを示している変数を示します配列の任意の位置に配置されます。

このように、ユーザーがボタンをクリックしてアイテムを削除するか、値フィールドに何かを入力するたびに、時計がトリガーされます。しかし、それは動作しません。

このように、ユーザーがボタンをクリックしてアイテムを削除するか、値フィールドに何かを入力するたびに、時計がトリガーされます。しかし、これは動作しませんし、私は次のように、「this.recompute()」メソッドが呼び出されるべきすべてのポイントをマッピングするために必要なのです:

onClickRemoveItem(event, part, item) { 
    ... 
    this.recompute() // RECOMPUTE HERE. 
}, 

onKeyupItemValue(event) { 
    this.recompute() // RECOMPUTE HERE. 
}, 

私は、これは解決する良い方法はないと思いますなぜなら、 "this.recompute()"メソッドを呼び出す場所が10以上あると、すべての呼び出し場所を覚えるのが難しくなるからです。

もっとエレガントな方法でこれを行う方法がありますか?

答えて

0

計算されたプロパティを合計すると、より多くの反応が得られます(つまり、アイテム値の更新をリッスンする必要はなく、何かを明示的に再計算する必要はありません)。特定の実装のために、ここでの回答を参照してください:https://jsfiddle.net/16wk9gre/

HTML

<script src="https://unpkg.com/vue"></script> 
<div id="app"> 
    <h3>Tests</h3> 
    <ul> 
    <li v-for="part in parts"> 
     <span>{{ part.name }}</span> 
     <ul> 
     <li v-for="item in part.items"> 
      R$ <input type="number" v-model="item.value"> 
      <button type="button" @click="onClickRemoveItem($event, part, item)">Remove</button> 
     </li> 
     <p> 
      Part subtotal: ${{ part.items.reduce((acc, item) => acc + parseFloat(item.value), 0) }} 
     </p> 
     <p> 
      Part subtotal (alternate): ${{ calculatePartSubtotal(part.items) }} 
     </p> 
     </ul> 
    </li> 
    </ul> 

    <p><strong>Total value:</strong>R$ {{ total }}</p> 
</div> 

JS

new Vue({ 
    el: '#app', 
    data() { 
    return { 
     // Define some nested mock data. 
     parts: [ 
     { id: 1, name: 'Part 1', items: [{ id: 1, value: 10.00 }, { id: 2, value: 5.00 }] }, 
     { id: 2, name: 'Part 2', items: [{ id: 3, value: 15.00 }] } 
     ] 
    } 
}, 
computed: { 
    total() { 
    let total = 0.0 
    for (let i = 0; i < this.parts.length; i++) { 
     for (let j = 0; j < this.parts[i].items.length;; j++) { 
     total += parseFloat(this.parts[i].items[j].value) 
     } 
    } 
    return total 
    } 
}, 
methods: { 
    calculatePartSubtotal (items) { 
    return items.reduce((acc, item) => acc + parseFloat(item.value), 0) 
    }, 
    // Remove an item of a part. 
    onClickRemoveItem(event, part, item) { 
    let index = part.items.findIndex(e => e.id === item.id) 
    this.$delete(part.items, index) 
    } 
} 
}) 
あなたの答えの@SciGuyMcQため
+0

おかげで、それは "合計" のために大いに役立つだろうが、私はしたい場合このパーツのすべてのアイテム値の合計である各パーツに対して合計1を計算するか?この場合、どのようにして計算されたプロパティを宣言できますか? –

+0

Ok。入力タイプをnumberに変更し、reduce関数で値を浮動小数点として解析し、パーツごとの小計を得ることができます。私は答えとJSFiddleを編集しました。メソッドにそれを抽出し、それを渡すこともできます。{{calculatePartSubtotal(part.item)}} 'のような項目。 – SciGuyMcQ

+0

今すぐどうぞ? – SciGuyMcQ

関連する問題