Reputation: 1739
Here is a very basic example of a computed observable in knockout:
let value = 'hello';
const co = ko.computed({
read: function() { return value; },
write: function(arg) { value = arg; }
});
console.log(co()); // Outputs 'hello'
co('bye'); // Update the value
console.log(value); // Outputs 'bye'
console.log(co()); // Still outputs 'hello' when value is already set to 'bye'
I traced this problem down to finding that the co's status immediately has isDisposed = true, so it was disposed. But why? By whom?
Even if I put a subscription on it right after creating it, it is still immediately disposed and will just not work.
I suppose maybe I have to somehow applyBindings, but I isolated that problem to where I actually do applyBindings (at least at some point). How else could I first set up an ViewModel (as they call it) and then bind it, if this computed gets disposed immediately?
Now if I had made the value an observable too
let value = ko.observable('hello');
const co = ko.computed({
read: function() { return value(); },
write: function(arg) { value(arg); }
});
console.log(co()); // Outputs 'hello'
co('bye'); // Update the value
console.log(co()); // Outputs 'bye'
Then it suddenly works. But that's dumb! If I just want an observable variable I'd use that. Instead I use a computed because it interacts with some system resource, say a database, and write will change the value in the database, and then read should give that value. If the database value changes something might trigger explicitly this computed as dirty to force re-evaluation, that's a problem for later.
Right now I notice that there seems no way to get the evaluation to work at all because it is considered disposed!
Upvotes: 1
Views: 54
Reputation: 292
If this code is your exact situation, then you have just re-created a basic observable. And no computed is necessary at all. And it's possible we are overthinking it.
As you noticed yourself in the 2nd part of the question. It works if "value" is observable. Which to me makes sense, since you are trying to observe any changes to that variable, just with more steps.
The overhead is so small and easy. I would say just do it, as is consistent with Knockout. Knockout is relatively dated anyway. I still use it all the time in legacy apps. But it's definitely not perfect. And I've been aiming to replace it with something newer where possible.
It's also possible that ko "subscribe" is more appropriate for your needs than ko "computed". Since it looks like you are trying to have one thing depend on another.
Upvotes: 0