0

In knockout I want to write an ComputedObservable which is computed from values which are not observable. I want to manually trigger the Notification.

Is this possible somehow?

Jason Aller
  • 3,391
  • 28
  • 37
  • 36
Jochen Kühner
  • 1,233
  • 1
  • 17
  • 39

2 Answers2

1

A computed variable is nothing but a function that registers custom event on all observables inside it.

When ever your internal observable variable changes, it broadcasts a notify event and all listeners catches the event and process accordingly.

The process sounds simple but isn't when you plan to use on plain Javascript variable. You can refer Listening for variable changes in JavaScript or jQuery.

Now if you wish to achieve this manually, basic challenges:

  • A variable can be changed anywhere, anytime. You will have to manually trigger their notify event everywhere. If you miss, you will have incorrect data.
  • You will also have to add eventListeners for bindings. Like a total variable which should be computed.
  • Browser support. IE8 or before does not support custom events and you will have to add hacks for it.

My suggestion, use computed (or pureComputed if on or above KO3.2) with observables. This way you will save a lot of code. Knockout team must have gone through these issues and have added handling for it in their code. You reinventing the wheel will add a lot of code in your codeBase and without proper documentation, will be difficult to maintain.

Following is a Fiddle where I replicated textInput binding for number input. If you see, they have separate handling of IE10, IE9 and IE8 or below. They even have special handling for safari below 5.

Community
  • 1
  • 1
Rajesh
  • 21,405
  • 5
  • 35
  • 66
  • I want to use knockout, and I want to use PureComputed. My only question is, hom can I raise a changed event, so all Controls bound to my PureComputed are refreshed? Because inside the pureComputed I do not use Observables – Jochen Kühner Oct 24 '16 at 07:05
  • I already tried: this.value.notifySubscribers("blabla") where this.value is my pureComputed observable, but my UI gets not refreshed – Jochen Kühner Oct 24 '16 at 07:06
  • Thats the point. If there is no observables inside computed function, there is no notify event and on change of these variable, computed will not be fired. So on `notifySubscribers`, subscribers will receive same value. – Rajesh Oct 24 '16 at 07:07
0

I fully agree with the other answer on just using ko.observable variables in your computed. I don't see why you'd use a computed if its re-evaluation isn't automated. I'd advice to create a plain function instead.

The closest approach I'd see is to create a dummy observable that the computed subscribes to. You can call valueHasMutated to force re-evaluation:

var a = "A";
var b = "B";

var subscriptionObs = ko.observable();

var ab = ko.pureComputed(function() {
  subscriptionObs();
  return a + b;
});

ko.applyBindings({ab: ab });


b = "C";
subscriptionObs.valueHasMutated();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<p data-bind="text: ab"></p>
user3297291
  • 19,011
  • 1
  • 24
  • 39