【问题标题】:Knockout.js binding gets broken when property of ViewModel renamed当 ViewModel 的属性重命名时,Knockout.js 绑定被破坏
【发布时间】:2016-07-01 23:39:07
【问题描述】:

这是我第一次在这里提问,所以请多多包涵:)

在一个由 knockout.js 支持的 MVC Web 应用程序中,我有,例如:

  1. C# 中的简单 ViewModel 类:

    public class RetailCustomer
    {
        public DateTime BirthDate { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
    
  2. 在 MVC 视图上的 knockout.js 中的简单绑定:

    function CustomerCtxViewModel() {
        var self = this;
        self.FirstName = ko.observable('');
        self.LastName = ko.observable('');
        self.BirthDate = ko.observable('');
        $.getJSON("/api/RetailContext", function (data) {
            self.FirstName(data.FirstName);
            self.LastName(data.LastName);
            self.BirthDate(data.BirthDate);
        }
    }
    

然后我将RetailCustomer 类中的属性BirthDate 重命名为Birthdate,因为代码分析告诉我...当然绑定不再起作用,最糟糕的是我发现了仅在运行时。

问题:是否有任何工具和技术可以在编译时或自动构建期间尽早警告我,以便我可以在应用程序运行之前看到我的错误?

【问题讨论】:

  • 国际海事组织编号 .由于 html 是在运行时呈现的,所以通常我们会在应用运行时看到错误。
  • 如果你不想被否决,你应该了解什么是主题,什么不是主题。询问工具建议绝对不是主题。阅读tour 中的“获取实用、详细问题的答案”部分。除此之外,你会做得很好。
  • @will,感谢您的反馈。我宁愿找出在这里有用的任何解决方案,无论是编码技术还是软件开发工具,并且这两者都在游览页面上明确说明为我应该询问的主题;)
  • 和“软件开发工具”仅上面两行

标签: javascript c# asp.net-mvc mvvm knockout.js


【解决方案1】:

超酷是正确的:绑定发生在运行时,并且 viewmodel 是一个动态对象,因此没有实用的方法来确保 viewmodel 和所需的绑定在编译/构建时匹配。

原则上,如果您使用的是 TypeScript,构建过程可以分析 HTML 并从中推断出一个接口,然后可以将其应用于您的视图模型,但即使这样也只是一般的applyBindings 的情况,它适用于整个 HTML 文档。 applyBindings 可用于单个 HTML 元素。这将是一个非常复杂的系统,据我所知,没有任何类似的尝试。

【讨论】:

    【解决方案2】:

    对于这种情况,您可以使用 @Html.NameFor 帮助程序,以防您的数据对象(JSON)与 .cshtml 文件中的模型类型相同。如果要在编译时验证语法,可以编辑 csproj 并将 MvcBuildViews 定义为 true。这样,您将在编译时知道 Razor 何时会失败。如果编译有问题,请查看this question

    【讨论】:

      【解决方案3】:

      我没用过,但是T4TS可以从C#类生成TypeScript接口定义。

      C#:

      [TypeScriptInterface]
      public class RetailCustomer
      {
          public DateTime BirthDate { get; set; }
          public string FirstName { get; set; }
          public string LastName { get; set; }
      }
      

      JavaScript:

      $.getJSON("/api/RetailContext", function (data: T4TS.RetailCustomer) {
          self.FirstName(data.FirstName);
          self.LastName(data.LastName);
          self.BirthDate(data.BirthDate);
      }
      

      我还发现了TypeLITE,它的作用大致相同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-11
        • 2018-07-30
        • 2021-05-12
        • 2016-12-17
        • 2023-03-15
        • 1970-01-01
        相关资源
        最近更新 更多