0

Edit: This answer here seems to have provided the solution; because I am a lazy sod and was trying to avoid having to define my model in two places (once on server, once on client) I figured there had to be a way. By using the custom binding in the linked solution, I'm able to have the observables created from the various form element data-bind attributes, so basically it builds the model from the form. So it's effectively driving the model definition from the form. I haven't decided yet if this is a bad idea :)

I'm wondering what I'm doing wrong (or indeed, if I even am doing anything wrong). I need to create a form to edit a single record at a time, which has just got some simple text/number properties:

{ItemCode:ABCD,LotNumber:1234,ID:4885,MeasuredValue1:90}

I decided to use ko with the mapping plugin to do it. I'm fairly new to ko. Anyway I ended up with a view model like this:

var LotModel = function() {
    var self = this;
    self.Update = function(itemcode,lotnumber) {
    var data = { ItemCode: itemcode, LotNumber: lotnumber }
//DoAjax is just a utility function and is working fine.
        DoAjax("POST", "LotHistory.aspx/GetLotHistory", data,
        function(msg) {
            ko.mapping.fromJS(msg.d, null, self);
            ko.applyBindings(self);
        },
        function(xhr, ajaxOptions, thrownError) {
            AjaxFailure(xhr, ajaxOptions, thrownError);
        }
        );
    }
}

And later on my code,

var lm = new LotModel();

and finally in $(document).ready

ko.applyBindings(lm);

Now it works, except that if you see in the view model, every time I load data I have to re-call ko.applyBindings(self) in the vm's Update function. If I comment out that line, it doens't bind. I think that this is because I'm only binding a single object (i.e the view model itself is the object after the ko mapping plugin does its work) but everywhere I read about ko it seems to say "you only need to call this once, ever." So I can't help feeling I am missing something really obvious; commenting out ko.applyBindings(lm) in the document ready function doesn't make any difference because I automatically call lm.Update in document.ready but commenting it out in the viewmodel breaks it.

So my question is - am I doing this the wrong way? Is it overkill for just a single object at a time type binding? I mean it doesn't bother me too much, it works as I want it to but still, it's nagging at me...

Community
  • 1
  • 1
Stephen Byrne
  • 7,400
  • 1
  • 31
  • 51

1 Answers1

1

It's indeed best not to reapply bindings many times if avoidable. The problem is that you don't have any observable properties in your viewmodel to begin with. An initial call to ko.mapping.fromJS can fix this (or you can manually add the observables) e.g.:

ko.mapping.fromJS({
    ItemCode: '', LotNumber: 0, ID: 0, MeasuredValue1: 0
  }, null, self);

See fiddle for a working example: http://jsfiddle.net/antishok/qpwqH/1/

antishok
  • 2,910
  • 16
  • 21
  • Thanks for the assist. Mentioning that the observables didn't exist gave me a big clue. Have found a possible solution here [http://stackoverflow.com/questions/6735225/knockout-js-mapping-plugin-without-initial-data-empty-form]. – Stephen Byrne Jan 24 '13 at 22:58