2016-11-02 9 views
1

Ich benutze Knockout, um etwas zu tun, das ich dachte, ist einfach. Ich bin neu in Knockout und JavaScript, also stecken geblieben. Jede Hilfe wird sehr geschätzt. Nachfolgend ist das Problem zur Hand.Berechnete Observable Array von Observable Arrays

Ich habe drei Inventare von Produkten (Öffnen, Schließen, geliefert) in Form von Array und ich möchte das verkaufte Produktinventar in Form von Array berechnen. Die tatsächlichen Daten sind etwas komplex. Hier ist die vereinfachte Version meiner Daten

var OpeningGasInventories = [{ 
    Id: 0, 
    Volume: 0, 
    TimeStamp: "0001-01-01T05:00:00Z", 
    GasInventoryType: "Opening", 
    GasProductId: 1, 
    ShiftId: 1 
}, { 
Id: 0, 
    Volume: 0, 
    TimeStamp: "0001-01-01T05:00:00Z", 
    GasInventoryType: "Opening", 
    GasProductId: 2, 
    ShiftId: 1 
}]; 

var ClosingGasInventories = [{ 
    Id: 0, 
    Volume: 0, 
    TimeStamp: "0001-01-01T05:00:00Z", 
    GasInventoryType: "Opening", 
    GasProductId: 1, 
    ShiftId: 1 
}, { 
Id: 0, 
    Volume: 0, 
    TimeStamp: "0001-01-01T05:00:00Z", 
    GasInventoryType: "Opening", 
    GasProductId: 2, 
    ShiftId: 1 
    }]; 


var DeliveredGasInventories = [{ 
    Id: 0, 
    Volume: 0, 
    TimeStamp: "0001-01-01T05:00:00Z", 
    GasInventoryType: "Opening", 
    GasProductId: 1, 
    ShiftId: 1 
}, { 
Id: 0, 
    Volume: 0, 
    TimeStamp: "0001-01-01T05:00:00Z", 
    GasInventoryType: "Opening", 
    GasProductId: 2, 
    ShiftId: 1 
    }]; 

var SoldGasInventories = [{ 
    Id: 0, 
    Volume: 0, 
    TimeStamp: "0001-01-01T05:00:00Z", 
    GasInventoryType: "Opening", 
    GasProductId: 1, 
    ShiftId: 1 
}, { 
Id: 0, 
    Volume: 0, 
    TimeStamp: "0001-01-01T05:00:00Z", 
    GasInventoryType: "Opening", 
    GasProductId: 2, 
    ShiftId: 1 
    }]; 

var GasProductSales= [{ 
    Id: 1, 
    CashPrice: 1.919, 
    CreditPrice: 0, 
    VolumeCashSale: 0, 
    VolumeCreditSale: 0, 
    AmountCashSale: 0, 
    AmountCreditSale: 0, 
    GasProductId: 1, 
    GasProductName: "Regular", 
    ShiftId: 1 
}, { 
    Id: 2, 
    CashPrice: 2.379, 
    CreditPrice: 0, 
    VolumeCashSale: 0, 
    VolumeCreditSale: 0, 
    AmountCashSale: 0, 
    AmountCreditSale: 0, 
    GasProductId: 2, 
    GasProductName: "Premium", 
    ShiftId: 1 
}]; 

Es folgt mein Knokcout Code Summen jedes Inventar und berechnen die verkauften Inventar Array

var AppViewModel = function() { 
var self = this; 

    self.OpeningGasInventories = ko.mapping.fromJS(OpeningGasInventories); 
    self.ClosingGasInventories = ko.mapping.fromJS(ClosingGasInventories); 
    self.DeliveredGasInventories = ko.mapping.fromJS(DeliveredGasInventories); 
    self.SoldGasInventories = ko.mapping.fromJS(SoldGasInventories); 
    self.GasProductSales = ko.mapping.fromJS(GasProductSales); 


self.TotalOpeningGasInventory = ko.computed(function() { 

     // Now calculate the sum of all Open Gas inventories 
     var total = 0; 
     self.OpeningGasInventories() 
      .forEach(function(item, index) { 
       total += +item.Volume() || 0; 
      }); 

     return total.toFixed(0); 
    }); 

    //Compute total of closing gas inventory 
    self.TotalClosingGasInventory = ko.computed(function() { 

     // Now calculate the sum of all Open Gas inventories 
     var total = 0; 
     self.ClosingGasInventories() 
      .forEach(function(item, index) { 
       total += +item.Volume() || 0; 
      }); 

     return total.toFixed(0); 
    }); 


    //Compute total of Delivered gas inventory 
    self.TotalDeliveredGasInventory = ko.computed(function() {    
     var total = 0; 
     self.DeliveredGasInventories() 
      .forEach(function(item, index) { 
       total += +item.Volume() || 0; 
      }); 

     return total.toFixed(0); 
    }); 

    //Compute total of Sold gas inventory 
    self.TotalSoldGasInventory = ko.computed(function() {    
     var total = 0;   
     self.SoldGasInventories() 
      .forEach(function(item, index) { 
       console.info("Volume is " + item.Volume()); 
       total += +item.Volume() || 0; 
      });   
     return total.toFixed(0); 
    }); 

    self.SoldGasInventories = ko.computed(function() {    
     //we know all the four arrays are in same order and of same length 

     for (var i = 0; i < self.SoldGasInventories().length; i++) {       

      self.SoldGasInventories()[i] 
       .Volume = parseFloat(self.OpeningGasInventories()[i].Volume()) + 
       parseFloat(self.DeliveredGasInventories()[i].Volume()) - 
       parseFloat(self.ClosingGasInventories()[i].Volume());   

     }   

     return self.SoldGasInventories(); 
    }); 
}; 

Ausgabe zu berechnen: Wenn ich kommentieren Sie die letzte berechnete Funktion self.SoldGasInventories dann werden alle Array-Summen in Ordnung berechnet. Diese letzte Funktion soll das SoldGasInvetories-Array berechnen, funktioniert aber nicht wie erwartet. Sobald ich diese Funktion auskommentiere, wird das self.TotalSoldGasInventory nicht aufgerufen. Ich habe eine JSFIDDLE erstellt Bitte überprüfen Sie und helfen Sie mir mein Problem zu lösen. Thanks a million ..

+2

Das liegt daran, dass Sie in 'SoldGasInventories()' nicht * das Observable * aktualisieren *, sondern stattdessen * es durch den Wert ersetzen. Probieren Sie '.Volume (...)' anstelle von '.Volume = ...' aus. Siehe https://jsfiddle.net/8nj31seh/45/ (nicht sicher, dass es richtig Werte nach der Änderung berechnet) – haim770

Antwort

1

Ihr letzter Computer gibt keinen berechneten Wert zurück, sondern aktualisiert andere Observable.

self.UpdateSoldGasInventoriesVolumes = ko.computed(function() { 
    //we know all the four arrays are in same order and of same length 
    for (var i = 0; i < self.SoldGasInventories().length; i++) { 
     self.SoldGasInventories()[i].Volume(
      parseFloat(self.OpeningGasInventories()[i].Volume()) + 
      parseFloat(self.DeliveredGasInventories()[i].Volume()) - 
      parseFloat(self.ClosingGasInventories()[i].Volume()) 
     ); 
    } 
}); 
+0

@ haim770 vielen Dank. Das hat das Problem gelöst. Danke eine Million –

+0

Dank dir auch. Ich konnte deinen Namen nicht in einen früheren Kommentar schreiben. –

+0

Ich habe eine zusätzliche Funktionalität hinzugefügt, die nicht wie gewünscht funktioniert. Ich möchte die zum Verkauf stehenden StoreProducts tabellarisch darstellen und dem Benutzer eine Eingabe für die Anzahl der verkauften Einheiten für jeden Artikel geben. Es sollte den "TotalAmount" (Preis * verkaufter Einheiten) aktualisieren und auch die Gesamtmenge aller verkauften Produkte bereitstellen. Hier ist [JSFIDDLE] (https://jsfiddle.net/8nj31seh/54/). Danke vielmals. –