【问题标题】:Attribute-based helper with lambda expressions for data-bind for integrating knockout.js with MVC4/5 + Razor基于属性的帮助器,带有用于数据绑定的 lambda 表达式,用于将 knockout.js 与 MVC4/5 + Razor 集成
【发布时间】:2014-04-04 04:20:27
【问题描述】:

我刚刚尝试了KnockoutMvc,虽然我很欣赏创作者的努力,但我发现它有点过于笨拙,一般来说没有用。不过,我喜欢尽量减少 Razor 视图中 JavaScript 的数量,尤其是样板 JavaScript(比如将我的服务器端视图模型绑定到客户端视图模型)。

是否有任何库允许您使用如下语法:

<span data-bind="@Html.DataBindFor(m => m.MyProperty)"></span>

或者,如果我要尝试编写自己的,大约需要哪些(非常通用的)组件才能使库有用?我假设我至少需要:

  1. 一组自定义属性,用于定义每个模型/属性/方法的绑定方式
  2. 在 Razor 视图中使用的一种扩展方法,用于使用反射找出属性值
  3. 一种用于 Razor 的扩展方法,用于生成(最小?)JavaScript 以将客户端视图模型绑定到 Razor 模型,并在必要时调用服务器

最后,假设这个库不存在,它不存在有充分的理由吗? IE 有没有办法真正解决这个问题,比如帮助方法,嗯,有帮助?

我问的原因是因为库 Lib.Web.Mvc.JqGrid 帮助我使用绝对最少的 JavaScript 非常快速地创建了交互式表格(刚好足以格式化列等),我想知道为什么 knockout.js 不存在相同的表格.

【问题讨论】:

  • 您熟悉ko.mapping 插件吗?它可以帮助您摆脱手动将服务器端模型转换为客户端视图模型的麻烦。
  • 它包含在我的视图中,但我没有使用它 - 我会使用 Html.Raw(Json.Encode(Model)) 序列化 ViewModel 吗?如果是这样,我想唯一要编写的 JavaScript 将是回调服务器的方法......
  • 我在回答中详细说明了一点。

标签: javascript asp.net-mvc asp.net-mvc-4 razor knockout.js


【解决方案1】:

摆脱手动将服务器端模型转换为客户端视图模型,您可以使用ko.mapping 插件,然后像这样使用它:

@model ViewModel

<script src="@Url.Content("~/Scripts/knockout.mapping-latest.js")" type="text/javascript"></script>

...

<script type="text/javascript">
    function ViewModel(initData) {
        var self = this;
        ko.mapping.fromJS(initData, {}, self);

        // Add custom view model logic
        ...

        // Logic for persisting the current state of the model back to the server
        self.Save = function() {                
            $.ajax('/model-uri', {
              type: 'POST',
              contentType: "application/json",
              data: ko.toJSON(self),
              success: function (response) {
                  alert('Success!');
              },
              error: function(xhr, status, error) {
                  alert('Error: ' + xhr.responseText);
              }              
         });
    };

    var initialData = @(Html.Raw(JsonConvert.SerializeObject(Model)));
    var model = new ViewModel(initialData);
    ko.applyBindings(model);
</script>

请注意,我们将服务器提供的视图模型序列化为 JavaScript 对象,然后使用 ko.mapping 插件使其属性可观察,这样我们就无需在客户端复制视图模型定义。在将更新的模型发送回服务器时,我们还使用了ko.toJSON 实用函数。

可以自定义映射过程以忽略某些属性:

var mapping = {
    'ignore': ["propertyToIgnore", "alsoIgnoreThis"]
}

ko.mapping.fromJS(data, mapping, self);

有更多可用的映射自定义,在plugin page 中进行了描述。

【讨论】:

  • 两个问题 - 1) 在您的回答中,save 完成的处理程序在哪里?一旦模型发布并得到响应,客户如何知道该怎么做? 2) 假设我的 ViewModel 非常大,和/或我的用户的 Internet 连接速度很慢。有没有办法在我的模型中只包含某些字段?
  • 1) 为了简洁起见,我省略了处理程序,现在添加。 2)添加到答案中。
  • 关于处理程序的另一个问题:我需要对响应做些什么吗?还是ViewModel 的成员是可观察的这一事实神奇地解决了这一问题?
  • 我想说最好的做法是让用户知道您正在尝试保存数据(例如,在发出 AJAX 请求之前显示“正在保存...”)并让他知道这是通过success 回调完成(例如,通过隐藏消息)。您必须处理服务器错误(通过error 回调),因为用户必须知道数据无法持久化。显示清晰可见的错误消息是合适的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-03
相关资源
最近更新 更多