KnockoutJS,ajax 调用后更新 ViewModel

Posted

技术标签:

【中文标题】KnockoutJS,ajax 调用后更新 ViewModel【英文标题】:KnockoutJS, updating ViewModel after ajax call 【发布时间】:2011-05-30 13:36:39 【问题描述】:

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

我的 MVC3 操作直接返回视图而不是 JSON,因此我将模型转换为 JSON。 这是一个数据输入表单,由于系统的性质,所有验证都在服务层中完成,并在 ViewModel 内的 Response 对象中返回警告。 初始绑定和更新工作正常,这是导致我出现问题的“更新后”行为。

我的问题是在调用 AJAX POST 并接收到我的 JSON 响应敲除后没有更新我的所有绑定...好像可观察/映射已经下降

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

这是 html/模板/绑定

<!-- 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 -->

这是淘汰赛/脚本

<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)。

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

【问题讨论】:

【参考方案1】:

我猜 Response 是保留的,当我将“Response”更改为“resp”时,一切正常。见http://jsfiddle.net/BBzVm/

【讨论】:

+正确,确实这是问题所在,现在将我的 viewModel 中的“Response”重构为“Messages”之类的东西。【参考方案2】:

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

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

【讨论】:

我之前尝试过您的建议并产生了相同的结果,但是您的参考是正确的,我将更新我的原始问题以使用 updateFromJSON。 我的错误是第一次使用 updateFromJS 是正确的,因为我在我的控制器中专门返回 Json(viewModel)。请查看上面的现场演示链接。

以上是关于KnockoutJS,ajax 调用后更新 ViewModel的主要内容,如果未能解决你的问题,请参考以下文章

knockoutjs:使用 ajax 调用发送 MultipartFile 和其他数据

将 knockoutjs 视图模型传递给多个 ajax 调用

将 KnockoutJS 可观察数组传递给 HTTP Post 控制器方法的 AJax 调用失败

通过 Jquery Ajax 函数加载后不渲染 KnockoutJS 元素

KnockoutJS 绑定

KnockoutJS - 我们可以为 CSS 更新调用 Observable 函数吗