knockout.js - Showing and hiding items based on a parent's value -


example jsfiddle


i have array of questions in model, following attributes:

  • id: simple enough, id of question
  • text: again, text question
  • parents: array of question ids question dependent on
  • activators: array of strings when parent's answer 1 of these values - question shown
  • answer: answer question
  • visible: boolean dictating whether question should visible on form

i'm using ko.mapping bind json string (of i'm retrieving asmx web method) view model.

i have bunch of primary questions have no parents or activators these should visible, bunch of dependent questions depend on respective parent(s) having value before dependent visible. can extend far depdendents being dependent on dependents (if see mean).

my initial thought (as i'm getting there knockout.js) subscribe answer property of question , grab sub-set of questions depend on 1 answered. have @ value, compare them activators , show / hide necessary.

viewmodel.questions().foreach(function (question) {     question.answer.subscribe(function (value) {         var dependents = viewmodel.questions().filter(function (q) {             return q.parents() && q.parents().indexof(question.id()) !== -1;         });          dependents.foreach(function (d) {             if (d.activators() && d.activators().indexof(value) !== -1) {                 d.visible(true);             } else {                 d.visible(false);                 d.answer(null);             }         });     }); }); 

while works, can't feeling i'm missing trick here. have use ko.mapping bind model view model it's been created me in asmx method, have extend view model (as i'm doing here cycling through questions , subscribing each one.

maybe should using ko.computed visible property, or maybe should creating kind of custom ko.bindinghandlers instead? i'm not sure. correct way of trying achieve want?

there several ways of achieving you're after, 1 of them using custom bindings mentioned.

whether or not that's considered "knockout-correct" way, won't say, it's different approach , might give ideas @ least. here's 1 way of creating binding handler:

ko.bindinghandlers.hideifirrelevant = {     update: function(element, valueaccessor, allbindingsaccessor, viewmodel, bindingcontext) {         var question = ko.unwrap(valueaccessor());          if(!question.parents()) {            $(element).show() // show question if has no parents            return false;         }          var allquestions = bindingcontext.$root.questions();         var parents = allquestions.filter(function (q) {             return question.parents().indexof(q.id()) !== -1;         });          var shown = false;         $.each(parents, function(i, parent) {             if(parent.answer() && question.activators().indexof(parent.answer()) != -1) {                 shown = true;                 return false;             }         });          if(shown) {             $(element).show();         }         else {             $(element).hide();         }     } }; 

here's updated fiddle. note using custom binding, no longer need visible property part of data model.


Comments

Popular posts from this blog

c++ - Creating new partition disk winapi -

Android Prevent Bluetooth Pairing Dialog -

VBA function to include CDATA -