我想创建一个松散的 TypeScript 类 MyKOArray<T> extends KnockoutObservableArray<T>
。这可能吗?如果是这样,有没有一种紧凑的方法可以做到这一点?
- 我读过 Knockout 的 extenders部分,但它似乎不适用,因为我试图(除其他外)添加
state
属性——不影响现有的可订阅内容。 - 我可以列出我尝试过的事情以及它们出错的方式(例如 TS2507、TS2322 等),但我怀疑它们是否能提供信息。作为基准,我认为一些基本细节是:
-
KnockoutObservableArray
是一个接口(interface),所以我真的需要“扩展”ko.observableArray
(“工厂”功能)。 ko.observableArray
的签名不正确(即没有new
并且它处理函数中的初始值而不是constructor
方法)。- 我可以
return ko.observableArray(initial)
来自构造函数,但无法获得正确的原型(prototype)链(例如方法不可用)。 - 我可以 override
@@create
在 JS 中为return ko.observableArray(initial)
,但我很难找到 JS 示例(更不用说有效的 TS 实现了)。
-
- 我还找到了 extremely old discussion关于类似的话题。结论是,由于 KO 中缺乏原型(prototype),这是不可能的,但当前的源代码(例如
ko.utils.setPrototypeOfOrExtend
)表明这个结论可能已经过时了。 - 我还挖掘了大量通用 TS 扩展问题(例如 Can you extend a function in TypeScript? ),但没有找到似乎匹配的内容。
===
编辑:为什么?
我正在尝试使用以下模式解耦我的系统(仅记录“有趣的案例”):
- ViewModel 向数据服务发出请求(间接通过类上的工厂方法)。数据服务立即返回一个实例(
MyClass
或KnockoutObservableArray<MyClass>
分别用于单例或集合)。 - 服务会异步加载/填充(并管理实时更新)返回的实例。这需要订阅 WebSocket 事件和 REST 调用来加载数据(包括重试的可能性)。
- 服务通过调用实例上的方法(我的模式中的“callback”和“errback”)将其进度传递给实例。
- 这些方法更新
state
属性(即可观察的),并且可能会更新其他内容(例如填充其值或填充可观察的错误消息)。 - UI 询问
state
可观察到向用户传达加载状态(和其他事件)。
这在我的单个实例上效果很好。 state
方法被广泛询问(和更新)以确保有效的行动。
我想在我的 KOArray 上复制该模式。这样,我可以区分尚未加载的空数组和恰好为空的已加载数组。我还可以添加 state
和error_message
到 KOArray 来镜像我的实例的行为。
最佳答案
简而言之,按照你描述的方式是不可能的。
更长的故事
Knockout 不是以面向对象的方式实现的。因此,基本上它公开的几乎所有内容都是函数或普通对象等。原型(prototype)处理用于扩展由例如 ko.observable 返回的函数实例。因此,从 OOP 意义上来说,基本上继承任何类型的 Knockout 内容都是不可能的。
如果您需要继承来添加功能,您可以将新方法添加到 ko.observableArray.fn 对象中。然后这个函数将可以在所有 observableArray 实例上调用。这里有一个简单的例子。
ko.observableArray.fn.hasElements = function() {
return this().length > 0;
}
...
if (myModel.selectedItems.hasElements()) {
...
}
如果您需要继承来限制某些内容,您可以添加自己的工厂函数,例如这样。
ko.myRestrictedObservableArray = function(initialValue) {
if (!initialValue || !initialValue.length) {
throw new "You can create an observable array only with a non-empty initial value";
}
return ko.observableArray(initialValue);
}
如果您愿意,您甚至可以覆盖原始函数,例如这样。尽管如此,在大多数情况下这并不是一个好的做法。
var _original = ko.observableArray;
ko.observableArray = function(initialValue) {
// ... do your custom things
var array = _original.call(this, initialValue);
// ... do your custom things
return array;
}
如果您还有其他要求,请在您的问题中更详细地描述。
关于typescript - (TypeScript) 扩展 KnockoutObservableArray,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48530291/