thomas gathings
thomas gathings

Reputation: 11

Can I access the viewModel after binding in Knockout?

I have created a master-details ui using Knockout. An itemselected event handler on the master binds a details view for the given data item. Everything works so far, but I would like to gain access to the data which was bound to the details area so I can post it to the server once updated.

I am new to Knockout, so please advise if there is a better approach to this.

//the master binding code
$.ajax({
url: getURL,
success: function (data) {
var viewModel = new itemModel(data);
var scope = document.getElementById("listContainer");
ko.cleanNode(scope);
ko.applyBindings(viewModel, scope);
}



//the viewmodel with event hander
function itemWrapper(item) {
    this.SolutionSet = ko.observable(item.SolutionSet);
    this.Insight = ko.observable(item.Insight);
    this.DateFrom = ko.observable(item.DateFrom);
    this.DateTo = ko.observable(item.DateTo);
}

var itemModel = function (data) {
    var self = this;
    var observableData = ko.utils.arrayMap(data, function (item) {
        return new itemWrapper(item);
    });

    self.items = ko.observableArray(observableData);
    onItemSelected = function (data) {
        var scope = document.getElementById("itemEditor");
        ko.cleanNode(scope);
        ko.applyBindings(data, scope);
    };
}

Upvotes: 1

Views: 730

Answers (2)

Tim
Tim

Reputation: 88

Your onItemSelected function should probably read self.onItemSelected (otherwise it's a global variable hanging off window).

You can use your second view model technique, or as Boone suggests, just have the form inside the first view model's scope and let Knockout parse it.

Add:

...
self.selectedItem = ko.observable();
self.onDetailsSubmit = function () { 
    self.selectedItem(null);
    // anything else you want to do
};
...

to your view model and update it with the selected item's index (or leave it null to hide the form).

<form data-bind="visible: selectedItem()">
    <!-- ko with: items()[selectedItem()] -->
    <input type="text" data-bind="value: SolutionSet" />
    <input type="text" data-bind="value: Insight" />
    <input type="text" data-bind="value: DateFrom" />
    <input type="text" data-bind="value: DateTo" />
    <button data-bind="click: $parent.onDetailsSubmit">Submit</button>
    <!-- /ko -->
</form>

I wrote this from memory, hopefully it works.

Upvotes: 0

Boone
Boone

Reputation: 1054

I'm assuming you have a form or something that you are then editing your details?

Just keep the submit in your viewmodel

var itemModel = function (data) {
   this.onFormSubmit = function (item) {
     //call ajax and pass you item
   }
}


<form data-bind="submit: itemModel.onFormSubmit">
   fields here like so
   <input data-bind='value: itemModel.DateFrom , valueUpdate: "afterkeydown"'/> 
</form>

Upvotes: 1

Related Questions