2017-10-31 15 views
3

Vuejsを初めて使用しましたが、いくつかのコードで問題が発生しています。Vuejsで作成された新しいオブジェクトが最後の値に更新されています

私は一連のline_itemsの注文をアイテムのリストに '平坦化'し、各オブジェクトのメタ情報を作成しようとしています。最初の部分は正常に機能しますが、Vuejsの反応的な性質が、これらの新しく作成されたオブジェクトの最後の値を以前のすべてのインカネーションにまたがっているように見えます。

私はここでフィーバーを作成しました。 http://jsfiddle.net/trestles/ruj7hzcf/3/

問題は自分のアイテムを作成すること(フィドル〜70行目)にあると推測します。

// here's the problem - why is quantity being updated to the last value? 
    var item = {item_id: line_item.menu_item_id, header: line_item.menu_item_header, quantity: line_item.quantity, locations: locations } 
    this.items.push(item); 

なぜこのアイテムを最後の値に更新するのですか?テーブルで

、結果は以下のとおりです。

test item 3 5 8 
spiced shrimp with horseradish cocktail sauce (per dozen) 9 5 8 
dates with bacon & parmesan (per dozen) 5 5 8 
marcona almonds (serves 8) 6 5 8 
marinated olives (serves 8) 8 5 8 

test item 3 3 0 
spiced shrimp with horseradish cocktail sauce (per dozen) 9 2 7 
dates with bacon & parmesan (per dozen) 5 5 0 
marcona almonds (serves 8) 6 0 6 
marinated olives (serves 8) 8 0 8 

私が間違って何をしていなければなりませんか?

答えて

3

既存のコードのほとんどの問題の根源は、同じオブジェクト(this.locationsthis.orderPickupTimesの配列)を再利用していることです。createNewItemを渡すと、何度も繰り返します。あなたのコード内にこれらの行を追加してください:

// instead of var location = this.locations[j]; 
var location = Object.assign({}, this.locations[j]); 

// and within the internal loop 
// instead of var order_pickup_time = this.orderPickupTimes[k]; 
var order_pickup_time = Object.assign({}, this.orderPickupTimes[k]); 

...という違いがあります。

それでも、問題の一部に過ぎません。あなたのコードの重要なアイデアは、それぞれの「アイテム」オブジェクト、つまり場所とピックアップ時間のリスト全体を保存することです。

しかし、これを行うには、すでに処理されたアイテム(構造が既に埋め込まれているアイテム)と新鮮なアイテムを区別する必要があります。それはそう、面倒だが、このようなもので動作するかもしれません:

var locations = []; 
var item = this.items.find(it => it.item_id === line_item.menu_item_id); 
if (item) { 
    locations = item.locations; 
} 
else { 
    item = {item_id: line_item.menu_item_id, header: line_item.menu_item_header, quantity: 0, locations: locations }; 
    this.items.push(item); 
} 

...これは新しい場所やorderPickupTimeの作成のどちらかを選択する必要があるすべての時間を繰り返してきた - または既存のものを再利用します。

ここでは、このアプローチを示すthe demoです。


ここでも2つの主要な部分を変更します。

まず、注文アイテムをその場所と受注時間でグループ化する専用プライベート機能を作成します。このような何か:それはヘッダアレイからの場所とorderPickupTimesの順番をとるように

function _groupItemsByOrders(orders) { 
    return orders.reduce(function(groupedItems, order) { 
    var locationId = order.location_id; 
    var orderPickupTimeKey = order.order_pickup_time_short; 
    order.line_items.forEach(function(lineItem) { 
     if (!groupedItems.hasOwnProperty(lineItem.menu_item_id)) { 
     groupedItems[lineItem.menu_item_id] = { 
      header: lineItem.menu_item_header, 
      quantity: 0, 
      locations: {} 
     }; 
     } 
     var groupedItem = groupedItems[lineItem.menu_item_id]; 

     if (!groupedItem.locations.hasOwnProperty(locationId)) { 
     groupedItem.locations[locationId] = {}; 
     } 
     var groupedItemLocation = groupedItem.locations[locationId]; 

     if (!groupedItemLocation.hasOwnProperty(orderPickupTimeKey)) { 
     groupedItemLocation[orderPickupTimeKey] = 0; 
     } 

     groupedItemLocation[orderPickupTimeKey] += lineItem.quantity; 
     groupedItem.quantity += lineItem.quantity; 
    }); 

    return groupedItems; 
    }, {}); 
} 

第二に、私はその後、groupedDataにマップし、そのテンプレートを再配置のです。このような何か:

<tr v-for="(item, item_id) in groupedItems"> 
     <td>{{item_id}}</td> 
     <td>{{item.header}}</td> 
     <td>{{item.quantity}}</td> 
     <template v-for="location in locations"> 
     <td v-for="opt in orderPickupTimes"> 
      {{item.locations[location.id][opt.short]}} 
     </td> 
     </template> 
    </tr> 

今、あなたの 'マウント' フックは次のようになります。

mounted(){ 
    axios.get('http://www.mocky.io/v2/59f8ceb52d00004d1dad41ec') 
    .then(response => { 
     this.locations = response.data.locations; 
     this.orderPickupTimes = response.data.order_pickup_times; 
     this.groupedItems = _groupItemsByOrders(response.data.orders); 
    }); 
} 

はここthe demoです。

+0

thx raina - ここ数日は走っていた。私はupvotedしかし、なぜ私が働いていないのかについてもっと多くの情報を与えることは可能です。私は詳細を反映するために賞金を加えました。もう一度。 – timpone

+0

もう一度答えを更新し、代替アプローチのデモを提供しました。ところで、ロギングでコードの振る舞いを確認するには、console.log(JSON.stringify(object))などを使用します。そうでなければ、オブジェクトの_latest_状態が表示されます。ロギング。 – raina77ow

関連する問題