Sid Kwakkel
Sid Kwakkel

Reputation: 799

knockout computed variables not showing

I have the following observables, but my totals don't update when I update my fields.

var formdata = ko.observable({
  a: 0,
  b: 0,
  c: 0,
  d: 0
});
var calcs = {
  calulatedValues: function() {
    this.total = ko.pureComputed(function() {
      return formdata().a+formdata().b+formdata().c+formdata().d;
    });
  }
}

$(function() {
  ko.applyBindings(formdata, document.getElementByID("myForm"));
  ko.applyBindings(calcs, document.getElementByID("totals"));
});

<div id="totals">
  <div data-bind="with: calculatedValues">
    <div data-bind="total"></div>
  </div>
</div>

Fiddle to show what's happening

Upvotes: 0

Views: 78

Answers (1)

adiga
adiga

Reputation: 35222

The with binding creates a new binding context. So you should change it from a function to:

var calcs = {
  calulatedValues: {
    total: ko.pureComputed(function() {
      return formdata().a + formdata().b + formdata().c + formdata().d;
    });
  }
}

And you are not binding total properly. Change it to:

<div id="totals">
  <div data-bind="with: calculatedValues">
    <div data-bind="text: total"></div>
  </div>
</div>

It still won't work properly because there is a typo in document.getElementByID("totals"). It should be Id

ko.applyBindings(calcs, document.getElementById("totals"));

Here's a fiddle


Update:

If you want the computed property to be triggered when a, b, c values get changed, then you should make them as observables, not formdata.

var formdata = {
  a: ko.observable(0),
  b: ko.observable(1),
  c: ko.observable(0),
  d: ko.observable(0)
};

and change the total to:

total: ko.pureComputed(function() {
  // added the "Number" parsing, otherwise it concatenates numbers as strings
  return Number(formdata.a()) + Number(formdata.b()) + Number(formdata.c()) + Number(formdata.d());
})

Updated fiddle

Upvotes: 2

Related Questions