knockout.js - Knockout JS Error: Cannot write a value to a ko.computed unless you specify a 'write' option -


having issue isn't game breaking. have simple table sort, , 2 filters. 1 filter populated array (active, inactive, show all) , 1 based on search criteria.

the code works. when have developer tools following error:

cannot write value ko.computed unless specify 'write' option. if wish read current value, don't pass parameters.

my code below, , set js fiddle can't work, i'm not sure it's helpful - fiddle

var sgsoip = window.sgsoip || {};  sgsoip.functionalarea = function (functionalareaid, functionalareaname, functionalareaactive) {      'use strict';      this.functionalareaid = ko.observable(functionalareaid);      this.functionalareaname = ko.observable(functionalareaname);//.extend({ required: "functional area name required" });      this.functionalareaactive = ko.observable(functionalareaactive);//.extend({ required: "active required" });      //this.haserror = ko.purecomputed(function () {      //    return this.functionalareaactive.haserror() || this.functionalareaname.haserror();      //}, this);  };    var sgsoip = window.sgsoip || {};  sgsoip.functionalareaviewmodel = function (ko) {      var self = this;      self.functionalareas = ko.observablearray([]);      self.search = ko.observable('');              self.headers = [          { title: '', sortpropertyname: '', asc: true, active: false },          { title: 'functional area name', sortpropertyname: 'functionalareaname', asc: true, active: true },          { title: 'active', sortpropertyname: 'functionalareaactive', asc: true, active: false }      ];      self.filters = [          { title: "show all", filter: null },          { title: "active", filter: function (item) { return item.functionalareaactive() === true; } },          { title: "inactive", filter: function (item) { return item.functionalareaactive() === false; } }      ];        self.activefilter = ko.observable(self.filters[0].filter);      self.activesort = ko.observable(function () { return 1; }); //set default sort        self.setactivefilter = function (model, event) {          self.activefilter(model.filter);      }            self.sort = function (header, event) {          //if header clicked second time          if (header.active) {              header.asc = !header.asc; //toggle direction of sort          }          //make sure other headers set inactive          ko.utils.arrayforeach(self.headers, function (item) { item.active = false; });          //the header clicked active          header.active = true;//our now-active header            var prop = header.sortpropertyname;          var ascsort = function (a, b) { return a[prop]() < b[prop]() ? -1 : a[prop]() > b[prop]() ? 1 : a[prop]() == b[prop]() ? 0 : 0; };          var descsort = function (a, b) { return a[prop]() > b[prop]() ? -1 : a[prop]() < b[prop]() ? 1 : a[prop]() == b[prop]() ? 0 : 0; };          var sortfunc = header.asc ? ascsort : descsort;            //store new active sort function          self.activesort(sortfunc);      };          self.filtereditems = ko.computed(function () {          var result;          if (self.activefilter()) {              result = ko.utils.arrayfilter(self.functionalareas(), self.activefilter());          } else {              result = self.functionalareas();          }            if (self.search()) {              return (ko.utils.arrayfilter(result, function (item) {                  return item.functionalareaname().tolowercase().indexof(self.search().tolowercase()) !== -1;              })).sort(self.activesort());          } else {              return result.sort(self.activesort());          }      });        self.removefunctionalarea = function (functionalarea) {          var con = confirm("are sure want delete record?");          if (con) {              $.post(                  '/functionalareas/deactivate',                  addantiforgerytoken({ id: functionalarea.functionalareaid }))                  .done(function () {                      self.functionalareas.remove(functionalarea)                      //var parentrow = datalink.parents("tr:first");                      //parentrow.fadeout('fast', function () {                      //    parentrow.remove();                      //});                  }).fail(function (data) {                      alert("error");                  });              return false;          }      }      function _init() {          //test code          var data =[{ functionalareaid: 1, functionalareaname: 'test', functionalareaactive: true },          { functionalareaid: 2, functionalareaname: 'atest', functionalareaactive: true },          { functionalareaid: 3, functionalareaname: 'ztest', functionalareaactive: false }];            //real code          //db.getfunctionalareas(function (data) {              var = [];              ko.utils.arrayforeach(data || [], function (item) {                  a.push(new sgsoip.functionalarea(item.functionalareaid, item.functionalareaname, item.functionalareaactive));              });              self.functionalareas(a);         // });      }      _init();      return {          sort: sort,          filtereditems: filtereditems,          setactivefilter: setactivefilter,          removefunctionalarea: removefunctionalarea      }  }(ko);    ko.applybindings(sgsoip.functionalareaviewmodel);
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>  <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>  <div class="container">  <div class="row">    <div class="col-sm-2 col-md-1">      <label for="searchstring">search:</label>     </div>    <div class="col-sm-3">      <input name="searchstring" class="form-control" id="searchstring" type="text" value="" data-bind="value: search, valueupdate: 'afterkeydown', event: { keyup: filtereditems } ">     </div>    <div class="col-sm-2 col-md-1">      <label for="filter:">filter:</label>    </div>    <div class="col-sm-3">      <div class="btn-group" data-bind="foreach: filters">        <button class="btn btn-default" data-bind="click:  setactivefilter, text: title">show all</button>      </div>    </div>  </div>        <div class="row extratopmargin">    <div class="col-sm-12">      <table class="table table-striped" id="gridoutput">        <thead>          <tr data-bind="foreach: headers">            <th><a href="#" data-bind="click: sort, text: title"></a></th>          </tr>        </thead>        <tbody data-bind="foreach: filtereditems">          <tr>            <td><a href="javascript:void(0);" data-bind="click: removefunctionalarea" title="delete"><i class="glyphicon glyphicon-trash"></i></a></td>            <td data-bind="text: functionalareaname"></td>            <td data-bind="text: functionalareaactive"></td>          </tr>        </tbody>      </table>    </div>  </div>    </div>

if type "z" you'll see works, error developer tools open. if remove code search criteria computed, , return result.sort(self.activesort()); no error occurs. i'm doing further refining result array inside computed, not sure violates how computed works, perhaps am.

you bind search input this

<input name="searchstring" data-bind="     value: search,      valueupdate: 'afterkeydown',      event: {          keyup: filtereditems     } ">  

which means knockout call filtereditems every time keyup event happens. filtereditems defined as:

self.filtereditems = ko.computed(function () { /* ... */ }) 

i.e. read-only computed. if call argument, knockout complain can't write read-only computed. don't that.

<input name="searchstring" data-bind="textinput: search">  

it's unclear event binding supposed achieve anyway.

also see: http://knockoutjs.com/documentation/textinput-binding.html


Comments

Popular posts from this blog

java - pagination of xlsx file to XSSFworkbook using apache POI -

Unlimited choices in BASH case statement -

apache - How do I stop my index.php being run twice for every user -