typescript - (TypeScript) 扩展 KnockoutObservableArray

标签 typescript knockout.js extends

我想创建一个松散的 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 向数据服务发出请求(间接通过类上的工厂方法)。数据服务立即返回一个实例(MyClassKnockoutObservableArray<MyClass> 分别用于单例或集合)。
  • 服务会异步加载/填充(并管理实时更新)返回的实例。这需要订阅 WebSocket 事件和 REST 调用来加载数据(包括重试的可能性)。
  • 服务通过调用实例上的方法(我的模式中的“callback”和“errback”)将其进度传递给实例。
  • 这些方法更新 state属性(即可观察的),并且可能会更新其他内容(例如填充其值或填充可观察的错误消息)。
  • UI 询问 state可观察到向用户传达加载状态(和其他事件)。

这在我的单个实例上效果很好。 state方法被广泛询问(和更新)以确保有效的行动。

我想在我的 KOArray 上复制该模式。这样,我可以区分尚未加载的空数组和恰好为空的已加载数组。我还可以添加 stateerror_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/

相关文章:

angular - @angular 或@types 中的 ‘@’ 符号后面是什么?

javascript - i18n.changeLanguage 不是函数

f# - 实现 F# 库以供 TypeScript/Javascript 使用?

javascript - knockout : Nested observableArrays and Nested ForEach

javascript - 如何创建双向 ko.compulated() 数组过滤器

java - 为什么泛型类型不适用于参数扩展父类(super class)?

Angular 2 -> 如何使用 FormGroup 隐藏控件

javascript - 带间隔的 knockout Ajax 仅显示更改的数据

java - 获取对象实例的原始类

java - 几个枚举如何扩展一个包含用于 Java 中这些枚举的方法的类?