使用映射和验证插件一起敲除。获取客户端错误

时间:2013-02-14 20:01:27

标签: knockout.js knockout-mapping-plugin knockout-validation

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

现在我正在尝试使用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 viewmodel的属性。有没有解决这个问题的方法?

3 个答案:

答案 0 :(得分: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});

答案 1 :(得分:1)

原始代码中的实际问题是您试图访问持有映射模型的observable上的Year属性,而不是模型本身(假设sDetailself上的extend() 1}}我只能假设你的实际视图模型)。这就是我在评论中的意思。您映射了 observable hold,因此您需要读取该值。您试图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

修复将调用你的observable来获取它所拥有的模型,然后你可以访问你想要的任何东西。

{{1}}

这不是要从最终的解决方案中取消,从映射设置中扩展将是首选,因为它会导致更清晰的代码(恕我直言)。

答案 2 :(得分:1)

对于更清晰,更易读的解决方案,请使用显式声明的VM

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

一样使用
new DetailsViewModel(data);

一个好的做法是明确声明所有执行域逻辑的成员。只有演示文稿的成员可以通过ko.mapping自动自动化。

更新:被某些douch拒绝投票,但此解决方案非常有效且可读

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