开发者

Manually subscribe and call updateFromJS causes dead-lock

I have some code below to make sure that a user does not need to click any button and update all input to server side. Server side code is responsible to perform any calculation and send updated JSON back 开发者_开发问答to client.

The issue here is that manual subscription code will detect the user input change, it will call to a function to post JSON data to server and receive JSON from server. From this point it will try to update the view model by calling ko.mapping.updateFromJS(viewModel, data);, but a dead-lock happens here. The updateFromJS will trigger the manual subscription event again, thus server code is called again, which triggers another round of manual subscription.

var initialData = /* get JSON from server side */;

var viewModel = ko.mapping.fromJS(initialData);

ko.applyBindings(viewModel, document.body);

viewModel.Product.Parameter1.subscribe(function(newValue) {
    postToServer();
});

viewModel.Product.Parameter2.subscribe(function(newValue) {
    postToServer();
});

viewModel.Product.Parameter3.subscribe(function(newValue) {
    postToServer();
});

function getProduct() {
    // retrieve JSON data to be posted to server side
}

function postToServer() {
    var product = getProduct();

    $.ajax({
        url: '/Home/ProductUpdate/',
        data: JSON.stringify(product),
        type: "POST",
        dataType: 'json',
        contentType: 'application/json; charset=utf-8',
        success: function (data) {
            // update JSON returned from server side to observable view-model
            ko.mapping.updateFromJS(viewModel, data);
        }
    });
}

Is it possible to do either of following:

  • Disable manual subscribe while ko.mapping.updateFromJS is called? (Resuming afterwards).
  • Have manual subscription ignore the event triggered by a ko.mapping.updateFromJS call?


Could you do it with a variable like so:

<script language="javascript" type="text/javascript">
var initialData = /* get JSON from server side */;

var viewModel = ko.mapping.fromJS(initialData);

var preventUpdate = false;

ko.applyBindings(viewModel, document.body);

viewModel.Product.Parameter1.subscribe(function(newValue) {
    if (!preventUpdate) postToServer();
});

and then in the postToServer function

success: function (data) {
    // update JSON returned from server side to observable view-model

    preventUpdate = true;
    ko.mapping.updateFromJS(data, viewModel);
    preventUpdate = false;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜