julianH
julianH

Reputation: 119

Knockout.js : What is the best way to trigger a calculation when a value in observable arrray changes

We have an observableArry of objects that contain observable properties (description, quantity, type).

These are maintained in a global list - call them supplementary items.

These items can be added to rows in a budget. Each row can contain 0 or more supplementary items - but can contain only ONE of each - no duplicates.

The budget line items have a unit cost value and a supplementary total column. The later is calculated as follows

this.suppitems().reduce((total, current) =>  current.isBillable() ? current.quantity() * this.unitcost() : 0, 0)

In other words if a Supplementary Item Type is Billable then multiply its quantity by the unit cost of the budget line item and add to the total Supplementary Item Cost for that row.

There is also a column that keeps track of the total supplementary items (sum of their quantites) assigned to the row. This is calculated as follows

this.suppitems().reduce((total, current) => total + +current.quantity(), 0)

All of this is fine - both the total items and the total cost for Supp Items update when you add / remove Supp Items from a row's Supp Item List.

However, when the quantity of a Supp Item already assigned to a row, is updated only the Supp Item Total (number of items) updates - the first calculation (calculating the total cost) does not fire.

One option is to add an observable to the Supp Item List object (parent that manages the observableArray of SuppItems) call it 'hasChanged'. In the Supp Item object subscribe to the quantity value and when it changes notify the parent list which in turn updates its hasChanged value.

Row items subscribe to hasChanged and when it fires call a method to re-calculate the total for the row. This works but I was wondering if there is a more elegant way of solving this?

Upvotes: 1

Views: 47

Answers (1)

julianH
julianH

Reputation: 119

I found the solution to the above.

The compute function as shown does work - the issue was Firefox developer edition - not sure what the cause was but when testing in all other browser including normal Firefox - problem did not manifest.

Upvotes: 0

Related Questions