我正在努力将一些旧的JS代码重写为CoffeeScript,并在此过程中清理它并将内容转换为更面向对象的格式。
我有一个用于用户编辑表单的Knockout.js视图模型。我还使用jQuery和knockout.validation进行客户端验证。我已将它转换为CoffeesScript类,效果很好。现在我正在转换其他一些代码(其他视图模型),我想为我的视图模型创建一个基类,其中包括所有这些视图模型共有的一些代码。但是我发现在基类上调用的方法不起作用,而在子类上调用的方法是。
以下是一个示例 - 用户视图模型:
这是原始代码:
class User
constructor: (values)->
// set up the view model properties as knockout observables
// set up the validation rules
bindKnockout: (@selector)->
// create a validated observable viewmodel & bind it to the
// DOM elements
ko.applyBindings(ko.validatedObservable(@), $(@selector)[0])
这很有效。创建表单后,将实例化用户模型,并调用bindKnockout
方法。
但我的大部分或全部视图模型都有一个相同的bindKnockout
方法,所以我认为我会从基类继承它:
class ViewModel
bindKnockout: (@selector)->
// create a validated observable viewmodel & bind it to the
// DOM elements
ko.applyBindings(ko.validatedObservable(@), $(@selector)[0])
class User extends ViewModel
constructor: (values)->
// set up the view model properties as knockout observables
// set up the validation rules
但是,当我这样做时,我的浏览器控制台出现错误:
Uncaught ReferenceError: Unable to process binding "disable: function (){return !isValid() }"
Message: isValid is not defined
Knockout抛出此错误,表示我的视图模型中没有isValid
可观察对象。通过knockout.validation插件将isValid
observable添加到视图模型中,并返回一个布尔值,指示模型是否通过验证。它存在并且在第一个示例中工作正常(没有基类),但是一旦我将它移动到基类就失败了。
我检查过我的源代码生成的Javascript。这是User模型中的原始代码(没有基本模型):
User.prototype.bindKnockout = function(selector) {
this.selector = selector;
return ko.applyBindings(ko.validatedObservable(this), $(this.selector)[0]);
};
在第二种情况下,继承基础模型:
Viewmodel.prototype.bindKnockout = function(selector) {
this.selector = selector;
return ko.applyBindings(ko.validatedObservable(this), $(this.selector)[0]);
};
鉴于代码是相同的,问题必须在于this
的绑定,对吧?但我已经为这两种方法做了console.log(@)
,但我找不到差异。
在这种情况下,任何人都可以解释继承是如何工作的(或者不按我期望的方式工作)吗?
答案 0 :(得分:0)
好的,我明白了。
如上所述,我将一堆旧的Javascript转换为CoffeeScript。这需要一些重组,特别是像jQuery和amp;昏死。事实证明,我实际上包括两次Knockout和Knockout.validation库 - 一次在我的HTML脚本标签中,一次在我的Javascript代码的依赖项中(我使用Browserify捆绑所有内容)。似乎Knockout或Knockout.validation并不喜欢......