Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update observable from the custom components in knockout 3.2

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?

like image 358
Salvador Dali Avatar asked Dec 20 '22 11:12

Salvador Dali


1 Answers

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

like image 78
Ilya Avatar answered May 04 '23 11:05

Ilya