1

我正在使用淘汰赛 js 在后端使用 asp.net mvc 4 构建我的应用程序。我们正在使用 knockout.mapping 来填充来自 MVC 服务调用的 observables

现在我正在尝试使用 Knockout.Validation 插件添加验证,如下所示:

self.sDetail(ko.mapping.fromJS(s));
var validationOptions = { 
                          insertMessages: true, 
                          decorateElement: true,      
                          errorElementClass: 'errorFill' 
                         };
ko.validation.init(validationOptions);
self.sDetail.Year.extend({ required: true });

当我运行它时,我收到以下错误:

Error: Unable to get property 'extend' of undefined or null reference

当我调试时,我发现 sDetail 显示为空。当我 applyBindings 输入正确填充。在什么时候我可以访问 ko 视图模型的属性。有没有办法解决这个问题?

4

3 回答 3

2

在这里找到了一个解决方案: Knockout Mapping Validation

基本上必须在对映射的调用中扩展属性

var validationMapping = {
// customize the creation of the name property so that it provides validation
Year: {
    create: function(options) {
        return ko.observable(options.data).extend( {required: true} );
    }
}
};


  self.sDetail(ko.mapping.fromJS(s,validationMapping));
 var validationOptions = { 
                      insertMessages: true, 
                      decorateElement: true,      
                      errorElementClass: 'errorFill' 
                     };
  ko.validation.init(validationOptions);

self.sDetail.Year.extend({ required: true });

于 2013-02-15T00:55:15.860 回答
1

原始代码中的实际问题是您试图访问Year保存映射模型的可观察对象上的属性,而不是模型本身(假设sDetail是一个可观察self对象,我只能假设它是您的实际视图模型)。这就是我在评论中的意思。您映射了observable 持有的,因此您需要读取该值。您尝试了extend()一个在可观察对象上不存在的属性,因此出现了错误。

self.sDetail; // <- your observable holding the model
self.sDetail.Year; // <- undefined, observables don't have a `Year` property
self.sDetail.Year.extend(...); // <- error

解决方法是调用你的 observable 来获取它持有的模型,然后你可以访问任何你想要的东西。

self.sDetail().Year.extend({ required: true }); // this should work

这并不是要从您的最终解决方案中删除,从映射设置中扩展将是可取的,因为它会导致更清洁的代码(恕我直言)。

于 2013-02-15T01:44:25.253 回答
1

要获得更清洁、更易读的解决方案,请使用显式声明的 VM

DetailsViewModel = function(data) {
   this.year = ko.observable().extend({ required: true });
   ko.mapping.fromJS(data, {}, this);
};

像这样使用

new DetailsViewModel(data);

一个好的做法是显式声明执行实际域逻辑的所有成员。ko.mapping 可以自动自动映射仅演示文稿的成员。

更新:被一些人否决了,但这个解决方案非常有效且可读

http://jsfiddle.net/hww8vk1n/1/

于 2013-02-15T09:31:06.580 回答