KnockoutJS,在ajax调用后更新ViewModel

时间:2010-12-25 02:07:03

标签: asp.net jquery asp.net-mvc-3 knockout.js

我正在使用Knockout和Knockout Mapping插件。

  • 我的MVC3 Action直接返回一个View而不是JSON,我将我的模型转换为JSON。
  • 这是一个数据输入表单,由于系统验证的性质,所有这些都在服务层完成,并在ViewModel中的Response对象中返回警告。
  • 初始绑定和更新正确地解决了导致我出现问题的“更新后”行为。

我的问题是在调用AJAX POST并且接收我的JSON响应后,敲除并没有更新我的所有绑定......好像observable / mappings已经下降

如果我包含一个额外的ko.applyBindings(viewModel);在成功中,事情确实有效......但是多个绑定会出现问题,并且我确定这不是正确的解决方案。

这是HTML / Template / Bindings

<!-- Start Form -->
<form action="@Url.Action("Edit")" data-bind="submit: save">
<div id="editListing" data-bind="template: 'editListingTemplate'"></div>
<div id="saveListing" class="end-actions">
    <button type="submit">Save Listings</button>
</div>
</form>
<!-- End Form -->

<!-- Templates -->
<script type="text/html" id="editListingTemplate">
        <div class="warning message error" data-bind="visible: Response.HasWarning">
            <span>Correct the Following to Save</span>
            <ul>
                {{each(i, warning) Response.BusinessWarnings}}
                    <li data-bind="text: Message"></li>
                {{/each}}
            </ul>
        </div>

        <fieldset>
            <legend>Key Information</legend>
            <div class="editor-label">
                <label>Project Name</label>
            </div>
            <div class="editor-field">
                <input data-bind="value: Project_Name" class="title" />
            </div>            
        </fieldset>        
</script>
<!-- End templates -->

这是Knockout / Script

<script type="text/javascript">
        @{ var jsonData = new HtmlString(new JavaScriptSerializer().Serialize(Model)); }

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


        viewModel.save = function () 
        {
            this.Response = null;
            var data = ko.toJSON(this);
            $.ajax({
                url: '@Url.Action("Edit")',
                contentType: 'application/json',
                type: "POST",
                data: data,
                dataType: 'json',
                success: function (result) {
                ko.mapping.updateFromJS(viewModel, result);
            }
        });
    }

    $(function() {                        
        ko.applyBindings(viewModel);            
    });
</script>

这是从成功请求返回的响应JSON,包括验证消息。

{
    "Id": 440,
    "Project_Name": "", 
    "Response": {
        "HasWarning": true,
        "BusinessWarnings": [
            {
                "ExceptionType": 2,
                "Message": "Project is invalid."
            }, {
                "ExceptionType": 1,
                "Message": "Project_Name may not be null"
            }
        ]
    }   
}

更新

Fiddler Demo是我正在经历的修剪现场示例。我使用返回的JSON更新了Project_Name,但是viewModel.Response对象和属性没有通过其数据绑定进行更新。特别是Response.HasWarning()。

我已经改回ko.mapping.updateFromJS,因为在我的控制器中我特意返回Json(viewModel)。

清理我的初始代码/问题以匹配演示。

2 个答案:

答案 0 :(得分:6)

我猜回应是保留的,当我将“响应”更改为“resp”时,一切都很顺利。见http://jsfiddle.net/BBzVm/

答案 1 :(得分:4)

你不应该在成功活动中使用ko.mapping.updateFromJSON吗? Knockout Mapping网站上的使用JSON字符串章节说:

  

如果您的Ajax调用返回一个JSON字符串(并且没有将其反序列化为JavaScript对象),那么您可以使用函数ko.mapping.fromJSON和ko.mapping.updateFromJSON来创建和更新您的视图模型。 / p>