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

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

jquery - Fancybox - apply a function to several elements -

An easy way to program an Android keyboard layout app -