knockout.js - Knockoutjs - Add to nested collection not updating UI -


i have view model has several layers of nested observablearrays.

viewmodel     - dictionaries[vmdictionary]         - concepts[vmconcept]             - termgroups[vmtermgroup]                 - language                 - terms[vmterm] 

i wish add instance of vmterm (the view model term object) specific instance of vmtermgroup, , have ui update automatically.

to achieve i've built function returns specific vmdictionary object:

function vmdictionaries(dicts) {      // other js removed brevity      self.dictionaries = ko.observablearray([]);      self.get = function (id) {         (var d = 0; d < self.dictionaries().length; d++) {             if (self.dictionaries()[d].id() == id) {                 return self.dictionaries()[d];             }         }         return null;     }; } 

once have specific vmdictionary object need obtain specific vmconcept object parent vmtermgroup i'm going add to. have id vmconcept can use retrieve it:

var concept; (var c = 0; c < dict.concepts().length; c++) {     if (dict.concepts()[c].id() == conceptid) {         concept = dict.concepts()[c];     } } 

inside vmconcept view model have function, addterm. function figures out vmtermgroup required checking each vmtermgroup's language.id property.

when matching vmtermgroup obtained, function pushes new vmterm vmtermgroup's terms observablearray.

function vmconcept(concept) {      // other js removed brevity      self.termgroups = ko.observablearray();     (var = 0; < concept.termgroups.length; i++) {         self.termgroups.push(new vmtermgroup(concept.termgroups[i]));     }      self.addterm = function (vmterm) {         // loop through termgroups         (var = 0; < self.termgroups().length; i++) {             // if termgroup.language matches vmterm.language...             if (self.termgroups()[i].language.id() == vmterm.language.id) {                 // ...then add vmterm termgroup                 self.termgroups()[i].terms.push(vmterm);                 return true;             }         }         return false;     }.bind(this); } 

however, when add new instance of vmterm vmconcept instance, ui doesn't update display it. can console.log number of vmterms in vmtermgroup both before , after call addterm , shows, example, 2 , 3, view never updated.

i've tried including call self.termgroups()[i].terms.valuehasmutated() makes no difference.

my suspicion @ 1 or more levels i'm bypassing knockout's observable array , diving directly inner (native) array, prevent knockout tracking changes, can't see how else can achieve i'm looking here.

i appreciate rather convoluted example/question, know how can add new vmterm inner-inner collection?

edit: here view template being used.

<div id="concept-container" data-bind="foreach: concepts">      <!-- markup removed brevity -->      <div data-bind="foreach: termgroups">         <div>             <div class="language-box" data-bind="text: language.title"></div>             <!-- ko foreach: terms -->                  <!-- markup removed brevity -->              <!-- /ko -->         </div>     </div> <!-- end of foreach: termgroups --> </div> <!-- end of foreach: concepts --> 

it's innermost foreach: terms i'm adding to, , isn't updating.

as jsfiddle, feared ask this. if above edit still doesn't i'll try put 1 together, quite removed actual work-in-progress , therefore may not true likeness.

i took different approach problem: instead of using jquery attach events, looping through view-model find required inner view-model, added event-binding knockout templates , used these call functions inside context view-model.

which arguably should have been doing start.


Comments

Popular posts from this blog

c# - Operator '==' incompatible with operand types 'Guid' and 'Guid' using DynamicExpression.ParseLambda<T, bool> -