【问题标题】:KnockoutJS & TypeScript (DefinitelyTyped): Adding Properties to ObservablesKnockoutJS & TypeScript (DefinitelyTyped):向 Observables 添加属性
【发布时间】:2016-05-30 18:54:30
【问题描述】:

在 KnockoutJS 中,您可以向 observableArrays 添加其他属性,例如:

class Table {

    items: KnockoutObservableArray<SomeType>;

    constructor() {
        this.items = ko.observableArray<SomeType>();
        this.items.someMethod = ko.pureComputed([...]);
    }
}

也就是说,TypeScript 会将someMethod 属性标记为错误并且不会编译。

上面的内容似乎适用于KnockoutObservable&lt;T&gt;,但不适用于KnockoutObservableArray&lt;T&gt;(使用DefinitelyTyped 的Knockout 定义文件)。

有没有一种方法可以允许这些额外的属性,而不必为每一个属性都使用以下属性?

/// Inside a custom definition file
interface KnockoutObservableArray<T> {
    someMethod: any; // Works, but is tedious and pollutes the definitions
    [x: string]: any; // Indexers don't work...
}

我也不热衷于使用any 来定义父属性。


编辑

好的,看来,为了让它工作,需要使用索引器选项,然后将动态属性引用为this.items['someMethod']() 而不是this.items.someMethod()。看起来 TypeScript 规范根本不允许在类定义中使用 dynamic 或任意属性。

【问题讨论】:

    标签: knockout.js typescript knockout-3.0 typescript1.6 definitelytyped


    【解决方案1】:

    如果您要将任意属性附加到类型化对象,我发现的最简单的方法是在您想要读取和写入这些属性时将对象转换为any。所以在你的情况下你会这样做:

     (self.items as any).someMethod = ko.pureComputed();
     var value = (self.items as any).someMethod();
    

    这种语法相当简洁,允许您访问任意属性,而不会丢失其他地方的一般类型保护。


    话虽如此,我绝对建议不要使用这种模式。像这样向库对象添加任意属性只会使代码更难以阅读和推理,并没有真正提供任何好处。假设someMethod 是特定于items 的一些逻辑,我会将someMethod 逻辑附加到父视图模型本身,或者如果有足够的与items 相关的逻辑,将该逻辑拉入它自己的包含项目列表和相关逻辑。

    【讨论】:

    • 感谢您概述铸造方法 - 我现在在一个实例中使用它。但你是对的——我真的应该把它移到主虚拟机上,或者实现一个子虚拟机。也就是说,这些任意属性过去非常方便,因为它们不包含在 ko.toJSON 调用中 - 所以我需要找到其他方法来保持对象的序列化干净。
    猜你喜欢
    • 1970-01-01
    • 2015-06-22
    • 1970-01-01
    • 2015-07-12
    • 2021-01-17
    • 1970-01-01
    • 2022-08-18
    • 2020-11-28
    • 2019-12-30
    相关资源
    最近更新 更多