javascript - Knockout Can I get around this computed loop? -
i have following structure bunch of objects in viewmodel
i have underlying array filled objects have ko.observable items in.
ex: selections = [{legs:{'0':ko.observable(12)}}, {legs:{'0':ko.observable(0)}}]
what trying achieve when user clicks on checkbox, should toggle selected value of runner. when happens update cache value reflect runners selected state
cache used binary storage 12 == 1100 == checkboxes 3 , 4 checked
now of can work no problem, don't need make cache observable.
but, have need programatically change cache values, , checkboxes reflect these changes automatically.
what below sorta works, creates loop, knockout gracefully handles, results unreliable , slows things down.
how can create binding setup?
function runner(name, odds, race, leg, post) { var runner = { name: name, odds: odds, post: post, race: race, leg: leg, cache: selections[race].legs[leg], selected: ko.observable(false), enabled: ko.observable(true), valid: true }; runner.check = ko.computed(function() { if (!this.enabled.peek() || !this.valid ) return; var checked = this.selected(); var cache = this.cache(); if (checked) { this.cache(cache | 1 << this.post); } else { this.cache(cache & ~(1 << this.post)); } }, runner); return runner; }
edit
<input type="checkbox" data-bind="checked: selected, enable: enabled"/>
i had moment of clarity after writing question. think question none less rather changing or removing question ill post newest solution , critique hopefully.
so in end forgo selected value entirely
note this.post + 1 specific needs, not needed normally, wish leave first bit unused future use.
runner.check = ko.computed({ read: function() { var cache = ko.utils.unwrapobservable(this.cache); //edit 1 return cache & 1 << (this.post + 1); }, write:function(value) { var cache = this.cache(); if (!this.enabled.peek() || !this.valid || this.post === -1) return; var mask = 1 << (this.post+1); if(value === !(cache & mask)){ //edit 2 this.cache(value ? cache | mask : cache & ~mask); } } }, runner);
one bad thing doing things way if have 20 runners use same cache, when user selects 1 of them 20 re-check themselves...
for specific case future change may removing peek on enabled, , performing check says if !enabled turn bit off default rather possibly allowing disabled checked checkbox.
edit
changed 'read' function use unwrapobservable() in case cache cleared ways of observable being deleted/removed elsewhere.
edit 2
while answering comment in original question realized prevent redundant calls add check see if bit's value equal value , if nothing, if programatically try turn on bit on won't fire computed since nothing has changed.
Comments
Post a Comment