web-dev-qa-db-fra.com

Utilisation de ko.utils.arrayForEach pour parcourir un tableau observable

J'essaie de calculer la somme du champ "prix" d'un "tableau observable". J'ai le code suivant jusqu'à présent:

(function(){

function objFeatures(name,price) {
        return {
            name: ko.observable(name),
            price: ko.observable(price),

            removeFeatures: function () {
                appViewModel.features.remove(this);
            }
        }
    }

var appViewModel = {
features: ko.observableArray([
            new objFeatures("Feature1", 20),
            new objFeatures("Feature2", 20)
        ]),

 grandTotal: ko.computed(function () {
            var total = 0;
            ko.utils.arrayForEach(this.features(), function () {
                total += this.price();
            })
            return total;
        })
};

ko.applyBindings(appViewModel);

}());

Quand j'essaye d'exécuter ceci, j'obtiens un "Erreur: this.features n'est pas une fonction" dans la console Firebug.

Qu'est-ce que je fais mal?

33
nthapa

Les observables calculés sont évalués immédiatement lors de la création. Dans votre cas, appViewModel n'a pas encore été créé et this ne représentera pas le appViewModel.

Il existe de nombreuses façons de garantir que this est correct dans ce cas. En voici deux:

  1. Créez-le en dehors de votre littéral d'objet initial:

    var appViewModel = {
       features: ko.observableArray([
           new objFeatures("Feature1", 20),
           new objFeatures("Feature2", 20)
           ])
    };
    
    appViewModel.grandTotal = ko.computed(function() {
        var total = 0;
        ko.utils.arrayForEach(this.features(), function(feature) {
            total += feature.price();
        });
    
        return total;
    }, appViewModel);
    
  2. Créez votre modèle de vue dans une fonction:

    var AppViewModel = function() {
        this.features = ko.observableArray([
            new objFeatures("Feature1", 20),
            new objFeatures("Feature2", 20)
        ]);
    
        this.grandTotal = ko.computed(function() {
            var total = 0;
            ko.utils.arrayForEach(this.features(), function(feature) {
                total += feature.price();
            });
            return total;
        }, this);
    };
    
    ko.applyBindings(new AppViewModel());​
    
60
RP Niemeyer