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
Post a Comment