ASP.NET MVC 5,Knockout.js和映射:正确的方法?

Sve*_*man 2 asp.net-mvc knockout.js

关于ASP.NET MVC,Knockout.js和映射插件的问题比比皆是.我有以下(非常简单的"入门")示例,它有效.但是,我想反馈一下这是否是推荐的方法.首先,我感兴趣的是未来的模型明显更复杂(儿童,下拉等).我觉得维护两套模型是不合理的,因此我希望使用映射插件.

PS:我不介意提交表单,但由于所有不同的问题,我无法让它工作,显然与ko.utils.postJSON引用的字符串值的URL编码有关.任何更新也将受到赞赏.

HTML

<h2>Simple View</h2>
<p>A simple model with 2 properties</p>
<p>Model property "Name": <span data-bind="text: Name"></span></p>
<p>Model property "Count" (just some integer): <span data-bind="text: Count"></span></p>
<form data-bind="submit: save">
    <h3>Editing</h3>
    <p>Name: <input type="text" data-bind="value: Name" /></p>
    <p>Count: <input type="text" data-bind="value: Count" /></p>
    <h3>Posting Back</h3>
    <button type="submit">Update</button>
</form>
Run Code Online (Sandbox Code Playgroud)

JavaScript的

<script type="text/javascript">
    var KoViewModel;
    $(function () {
        KoViewModel = ko.mapping.fromJSON('@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model))');
        ko.applyBindings(KoViewModel);
    });
    var save = function () {
        $.ajax({
            url: location.href,
            type: 'POST',
            data: ko.mapping.toJSON(KoViewModel),
            contentType: 'application/json; charset=utf-8',
            success: function (data) {
                ko.mapping.fromJSON(data, KoViewModel);
            }
        });
    }
</script>
Run Code Online (Sandbox Code Playgroud)

服务器端

public ActionResult Index()
{
    Models.SimpleModel m = new Models.SimpleModel();

    m.Name = "Some name";
    m.Count = 1;

    return View(m);
}

[HttpPost]
public JsonResult Index(Models.SimpleModel fc)
{
    fc.Name += " (updated)";
    fc.Count++;
    return (new JsonResult() { Data = Newtonsoft.Json.JsonConvert.SerializeObject(fc) });
}
Run Code Online (Sandbox Code Playgroud)

感谢您的任何见解!

Tom*_*lak 6

我会以不同的方式构建脚本.

function SimpleModel(data) {
    var self = this;

    // data
    self.Name = ko.observable();
    self.Count = ko.observable();

    // api
    self.load = function (data) {
        if (data) ko.mapping.fromJSON(data, {}, self);
    };
    self.save = function () {
        return $.ajax({
            type: 'POST',
            url: location.href,
            data: ko.mapping.toJSON(self),
            contentType: 'application/json; charset=utf-8',
        }).done(self.load);
    };

    // init
    self.load(data);
}

// later... -------------------------------------------------------------------------
$(function () {
    var data = '@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model))';
    ko.applyBindings( new SimpleModel(data) );
});
Run Code Online (Sandbox Code Playgroud)

好处:

  • 视图模型的所有数据属性都是显式定义的.这有助于减少错误,因为视图模型看起来很明显.它还有助于减少运行时错误,因为即使JSON输入上缺少属性,属性也会存在.这样,视图总是可以毫无问题地绑定.
  • 您可以将viewmodel移动到单独的脚本文件中.
  • viewmodel可以从传递给构造函数的数据初始化自身.如果您重构应用程序,这将非常有用 - 例如,当您的viewmodel突然成为更大的viewmodel的一部分时.
  • 没有对全局变量或单独的辅助函数的笨拙引用,viewmodel是自包含的.
  • save方法返回Ajax承诺允许您在不重新连接viewmodel的情况下附加额外行为:

    var vm = new SimpleModel(data);
    
    // programmatically save the model
    vm.save().done(function () {
        // whatever
        localStorage.setItem('lastAutoSave', Date.now());
    });
    
    Run Code Online (Sandbox Code Playgroud)

  • @rism OP确实说他"觉得"它"不合理"...... Tomalak试图证明这一点.我"觉得"他做到了:) (2认同)