Adam Rackis
Adam Rackis

Reputation: 83356

KnockoutJS Mapping - just fill in what I need from the server

One intuitive way I though I'd be able to use KO mappings plugin would be to create a naked viewModel with only whatever computed observables I needed, then update the vm with fromJS whenever server results came in. I assumed missing properties would be added, and existing ones would be updated.

I thought I could just bind this naked ViewModel to my dom on document.ready, with any missing properties showing up blank. Then, when an ajax callback fires, and the mapping library adds the new properties, the dom would update.

The results I saw seem to indicate that this isn't possible though, and I wanted to make sure I'm not missing anything.

The code is below, but the three main problems I found were:

I don't need any help working around this. I've already come up with a simple way to deal with all this; I just want to make sure there's not something simple I'm missing on any of the above three bullets that would make things more easy.


VM:

    var vm = new (function () {
        this.prettyName = ko.computed(function () {
                return this.title() + " " + this.name();
        }, this);
    })();

"AJAX" result:

    var serverObj = {
        title: 'Mr.',
        name: 'Adam Rackis',
        degreeValue: 2,
        degreeTypes: [{ val: 1, txt: 'Bachelors' }, { val: 2, txt: 'Masters' }, { val: 3, txt: 'PhD'}]
    };

HTML

<div id="educationPane">
    Name: <input type="text" data-bind="value: prettyName" />
    Degree: <select data-bind="{foreach: degreeTypes, value: degreeValue}">
                <option data-bind="{text: text, value: val}"></option>
            </select>
</div>

Upvotes: 1

Views: 131

Answers (1)

madcapnmckay
madcapnmckay

Reputation: 15984

I have hit all of these same issues when working with KO. Point 1 and 2 in my opinion is simply a consequence of how KO works.

  • When the dom is bound to a property that doesn't exist the binding needs to subscribe to the observable or display the property value in order to work. If you subsequently add that property to the viewModel how could the binding know that this had happened? (A more complex solution would be to allow viewModel objects themselves to be observable but that's another story)
  • When a computed observable is created it's containing function is evaluated immediately so that subscriptions to observables can be recorded and the computed can reevaluate when needed. If no observables exist (immediate error, can be fixed with a test) or none are hit within the computed's evaluation it will not be evaluated again.
  • -

Point 3 I concede is a pain. I don't know the reasons it was done this way. Maybe there were some good reasons. At the very least an 'update' method that simply updates properties and doesn't remove from collections would be useful.

Hope this helps.

Upvotes: 1

Related Questions