I have a grid with several columns that I want to aggregate data from. Let's say that the grid contains columns filled with numbers. The rightmost column should view the sum of all the numbers on the left. What I did was to implement a custom ValueProvider for this column. In the getValue method I add all the numbers of the proxy and return the result.
The problem with this approach is that the grid is only updated live if I set the store in autocommit mode. The ValueProvider always works with the backend model, not the internal records of the grid. Because of this, the original value will be given to the ValueProvider when it should update the grid data. The modified value remains in the grid store only. Because I am in autocommit mode, I will never see the red corner mark on the modified cells. If I disable autocommit the values will of course be updated when I prepare the backend model for persisting it.
Is there a better way to solve this problem, or does this need changes to the library?
The issue is that before values are committed, they are stored in a Store.Record instance, mapped to the property they will be setting. Your valueprovider is only reading the actual values in the model, and cannot see the Record to ask it questions.
One thought: listen to StoreRecordChangeEvents, and if the event happens to the first or second column, get the same record for the third column and modify it. This way when the Grid tries to read out values from the store, it will see that modified value instead of the original ValueProvide-created value. This will also draw a red marker in this column, which may make sense, given that this value has also changed. If you try to add a change to that record that would revert it back to the original value, it should mark that record as not dirty, and should then remove that red marker (i.e. A and B have initial values of 2 and 3, so C has 5. Change A to have 3 so C is red and 6, then change B to 2 so C is not red and 5 again. A and B then are red, but C is not).
Another thought: Use a custom cell in the third column, and have it act on the entire model (i.e. with an IdentityValueProvider), and put any logic needed in there. Have it hold a reference to the store, ask if the current object has a Record, and if so read values from there, otherwise create the value from the original getters.