【发布时间】:2015-09-14 22:39:11
【问题描述】:
我正在努力将一些旧的 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 observable。 isValid observable 由 knockout.validation 插件添加到视图模型中,并返回一个布尔值,指示模型是否通过验证。它在第一个示例中存在并且工作正常(没有基类),但是一旦我将它移动到基类它就会失败。
我检查了从我的源代码生成的 Javascript。这是来自用户模型的原始代码(没有基本模型):
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(@),但我找不到区别。
任何人都可以解释在这种情况下继承是如何工作的(或不按我期望的方式工作)吗?
【问题讨论】:
-
我做了一个小提琴 (jsfiddle.net/8crw6s1t) 来试试这个,我没有遇到错误。也许你可以修改它来演示问题。
-
你已经涵盖了我能想到的所有明显的潜在问题,但是如果我可以建议继承的替代方案,javascript 使 mixin 变得相当简单,并且它们更加解耦。类本身就是coffeescript中的值,编写一个将类作为其第一个参数并使用
...运算符收集可变数量的mixin并应用它们的辅助函数并不难。也许不是你要找的,但我只是被继承烧伤太多次了。 -
感谢@RoyJ 的提琴 - 今天早上我会花一些时间看看它。
标签: javascript knockout.js coffeescript