Reputation: 1138
Consider the following code:
<div class="expandedCoverages" data-bind="foreach: $root.getGroupCoveragesPerPackage(packageCost)">
<div class="calculateCostCoverage"
data-bind="html: CoverageGroupDescription()"></div>
</div>
</div>
If packageCost observable changes, CoverageGroupDescription() doesn't change since function isn't triggered again.
Is it possible somehow to trigger again the function so as to change the foreach binding?
Upvotes: 0
Views: 3531
Reputation: 10966
Under the hood this is what Knockout does with functions/ statements executed directly in the view (HTML):
Although using a computed property in the JS model, like Sam C.'s comment suggests, is cleaner, it is not absolutely necessary. Doing:
<div data-bind="foreach: myFunction(observableParam())"></div>
is actually the same as doing:
<div data-bind="foreach: myComputed"></div>
with:
this.myComputed = ko.computed(function() { return myFunction(observableParam()); });
That means in this case probably coverageGroupDescription
does not return a correctly updated array. See a working example with a more or less similar implementation as in the question, below. Change the packageCost and the descriptions will automatically change too.
var Coverage = function(cost) {
this.cost = ko.observable(cost);
this.coverageGroupDescription = function() {
return 'This package costs ' + this.cost() + '$';
}.bind(this);
}
var app = {
items: ko.observableArray([
new Coverage(15),
new Coverage(20),
new Coverage(25),
new Coverage(30),
new Coverage(35),
]),
packageCost: ko.observable(1),
getGroupCoveragesPerPackage: function(m) {
var m = m();
return ko.utils.arrayMap(this.items(), function(item, i) {
return new Coverage(item.cost()*m);
});
}
};
ko.applyBindings(app);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
Multiply all by: <input type="text" data-bind="value: packageCost">
<ul data-bind="foreach: getGroupCoveragesPerPackage(packageCost)">
<li data-bind="text: coverageGroupDescription()"></li>
</ul>
Upvotes: 2