knockoutjs writeable computed

knockout class binding

by andrew rowe

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<div data-bind="class: className, text: className">

</div>
<span data-bind="text: co, class:className"></span>
<button class="red" data-bind="click: ()=>toggle('red')">
red
</button>
<button class="yellow" data-bind="click: ()=>toggle('yellow')">
yellow
</button>

CSS

.red {
  background: red;
}

.yellow {
  color: yellow;
}

JavaScript

//let value = 'hello';

class ViewModel {
  constructor() {
    this.value = ko.observable('hello');
    this.co = ko.computed({
      read: () => {
        return this.value();
      },
      write: (arg) => {
        this.value(arg);
      }
    });
    this.classNames = ko.observableArray([]);
    this.className = ko.computed(() => this.classNames().join(' '))
  }

  toggle(value) {
    const i = this.classNames.indexOf(value);
    if (i >= 0) {
      this.classNames.splice(i, 1)
    } else {
      this.classNames.push(value);
    }
  }
}
vm = new ViewModel();
ko.applyBindings(vm);

console.log(vm.co()); // Outputs 'hello'

vm.co('bye'); // Update the value

console.log(vm.value()); // Outputs 'bye'

console.log(vm.co()); // Still outputs 'hello' when value is already set to 'bye'