【问题标题】:Manually subscribe and call updateFromJS causes dead-lock手动订阅并调用 updateFromJS 导致死锁
【发布时间】:2011-08-29 18:26:59
【问题描述】:

我在下面有一些代码来确保用户不需要单击任何按钮并将所有输入更新到服务器端。服务器端代码负责执行任何计算并将更新的 JSON 发送回客户端。

这里的问题是手动订阅代码会检测到用户输入的变化,它会调用一个函数来将 JSON 数据发布到服务器并从服务器接收 JSON。从这一点开始,它将尝试通过调用ko.mapping.updateFromJS(viewModel, data); 来更新视图模型,但这里会发生死锁。 updateFromJS会再次触发手动订阅事件,从而再次调用服务端代码,触发下一轮手动订阅。

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);
        }
    });
}

是否可以做以下任一操作:

  • 在调用ko.mapping.updateFromJS 时禁用手动订阅? (之后继续)。
  • 是否让手动订阅忽略由ko.mapping.updateFromJS 调用触发的事件?

【问题讨论】:

    标签: javascript knockout.js


    【解决方案1】:

    你能用这样的变量来做吗:

    <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();
    });
    

    然后在postToServer函数中

    success: function (data) {
        // update JSON returned from server side to observable view-model
    
        preventUpdate = true;
        ko.mapping.updateFromJS(data, viewModel);
        preventUpdate = false;
    }
    

    【讨论】:

    • 这是个好主意,我目前的做法是先禁用订阅,然后再重新启用。
    猜你喜欢
    • 1970-01-01
    • 2018-04-20
    • 2012-09-20
    • 2018-06-04
    • 2016-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多