简体   繁体   中英

Sum values in nested knockout observableArray

I Want to sum the nested Element QtyToOrder * VendorPrice For all the array elements based on the selected vendor.

My nested observable array that looks like this:

CheckStock: [{
        ItemName: "123",
        Vendors: [{
                         QtyToOrder: "5",
                         VendorPrice: "1243"}],
        SelectedVendor: 0
       },{
        ItemName: "123",
        Vendors: [{
                         QtyToOrder: "5",
                         VendorPrice: "1243"},
                   {
                         QtyToorder: 9
                         VendorPrice: 999 }],
        SelectedVendor: 0
       }]

I have created a Fiddle with my actual data that I use and the ViewModel that I am using. and this function:

 MyDataViewModel.TotalPurchaseReqPrice = ko.computed(function () {
        var self = MyDataViewModel;
        var tot;
        for (var i = 0; i < self.CheckStock().length; i++) {
            for (var j = 0; j < self.CheckStock()[i].SelectedVendor() ; j++) {
                var HasVal = self.CheckStock()[i].SelectedVendor()[j] ? (ko.toJS(SelectedVendor().QtyToOrder) * ko.toJS(SelectedVendor().VendorPrice)) : 0
                tot += HasVal
            }
        }
        return tot;
    });

To try and get it to work, but I do not get any value returned from my Viewmodel. I have also tried Subscribing to the SelectedVendor but keep getting that the SelectedVendor is undefined. Any Assistance would be greatly appreciated

Ok.. It got me a while to make this work, but I think I achieved what you wanted to do.

The main problem is that you are creating this property:

 MyDataViewModel.TotalPurchaseReqPrice = ko.computed(function () {}

But this never knows when it should be computed. In fact the properties that should trigger the change are not in the MyDataViewModel , they are in each of the CheckStock objects. I guess you want to trigger the recalculation when any of the dropdown changes, so this belongs to the property SelectedVendor of the objects of CheckStock .

So instead, we can do the following:

           var stock = {
                    ProductName: element.ProductName,
                    RequiredComponents: element.RequiredComponents,
                    StockCode: element.StockCode,
                    RequiredQtyByBom: element.RequiredQtyByBom,
                    QtyUnassignedInWarehouse: element.QtyUnassignedInWarehouse,
                    QtyAllocatedInWarehouse: element.QtyAllocatedInWarehouse,
                    PCBReference: element.PCBReference,
                    QtyOnOrder: element.QtyOnOrder,
                    SelectedVendor: ko.observable(0),
                    Vendors: ko.mapping.fromJS(element.Vendors),
                    RequireVendor: element.RequireVendor
                };

                stock.SelectedVendor.subscribe(subscription, MyDataViewModel);
                MyDataViewModel.CheckStock.push(stock);

Notice that in the subscribe function I'm passing the delagate to trigger and MyDataViewModel as the context. The subscription variable is the function to calculate the TotalPurchaseReqPrice . I made some changes here, maybe this function is not doing exacly what you wanted to do.. I did some interpretation :)

  var subscription = function () {
        var tot = 0;
        for (var i = 0; i < this.CheckStock().length; i++) {
            if(this.CheckStock()[i].SelectedVendor()){
                   tot += this.CheckStock()[i].SelectedVendor().QtyToOrder() * this.CheckStock()[i].SelectedVendor().VendorPrice();
            }            
        }
        this.TotalPurchaseReqPrice(tot);
    };     

I changed quite a lot of code, so better if you take al ook at this JsFiddle .

I hope this is more or less what you wanted to achieve.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM