I am trying to use custom components from knockout 3.2 and update the observable from within the component. Here is an example of my custom component:
ko.components.register('voting', {
viewModel: function(params) {
var self = this;
this.votes = params.votes;
this.yourVote = params.yourVote;
this.callback = function(num){
self.yourVote(parseInt(num)); // here I am updating
self.votes( self.votes() + parseInt(num) );
};
},
template: { element: 'voting-tpl' }
});
The template for it looks like this:
<voting params="votes: votes(), yourVote: yourVote()"></voting>
<template id="voting-tpl">
<div data-bind="click:function(){callback(1)}">Up</div>
<div data-bind="text: votes"></div>
<div data-bind="click:function(){callback(-1)}">Down</div>
</template>
The problem is that when I click on Up/Down function in my full JS fiddle. I get
Uncaught Error: Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.
Surely I can use var a = new Vm();
and update it from inside of the component with a.yourVote(num);
but this breaks the whole idea of components.
How can I do it properly?
You should pass your observables as parameters to custom component, instead of creating dependencies:
<voting params="votes: votes, yourVote: yourVote"></voting>
You can read more here knockout 3.2 components (How params are passed to the component)
The params are provided to initialize the component, like in the component binding, but with a couple of differences:
- If a parameter creates dependencies itself (accesses the value of an observable or computed), then the component will receive a computed that returns the value. This helps to ensure that the entire component does not need to be rebuilt on parameter changes. The component itself can control how it accesses and handles any dependencies.
Fixed JSFiddle DEMO
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With