我遇到的情况是我在typescript中构建一个基类,并且该类的一部分定义了一个错误计算的observable:
public hasError: KnockoutComputed<boolean>;
在类的构造函数中,我使用一个总是返回false的简单函数来定义它:
this.hasError = ko.computed<boolean>((): boolean => { return false});
目的是该类的用户将定义任何有意义的函数来定义此类是否有错误。这样做很好,因为通常hasError变量在使用之前已经重新定义,并且using代码将引用新重新定义的计算。
但是,我现在正在向基类添加功能,该基类将基于类中的其他状态和hasError的状态而具有另一个计算集。它将被定义为:
this.success = ko.computed<boolean>((): boolean => {
return !this.hasError() && this.complete();
});
问题是this.success现在绑定到hasError的简单定义,它始终返回false,因为在使用代码有机会重新定义hasError之前它已绑定到它。
有没有一种计算方法可以重新定义其功能?我假设如果我可以重新定义hasError的函数,并发送一条消息说hasError已经变异,那么成功的定义将继续正常运行,因为它链接到计算的实例,而不是函数最初用于定义计算。
我正在使用knockout v3.4.something。
由于
答案 0 :(得分:1)
如果计算出的hasError本身包含在一个observable中,那么您的二次计算将被通知函数的更改。您必须先调整用法来解开函数,但如果需要,可能会在属性getter / setter后面抽象出来。
class TestBase {
public success: KnockoutComputed<boolean>;
public complete: KnockoutComputed<boolean>;
public hasError: KnockoutObservable<KnockoutComputed<boolean>>;
constructor() {
this.hasError = ko.observable(ko.computed<boolean>((): boolean => { return false; }));
this.success = ko.computed<boolean>((): boolean => {
var hasError = this.hasError();
return !hasError() && this.complete();
});
}
}
class Test extends TestBase {
constructor() {
super();
this.hasError(ko.computed<boolean>((): boolean => { return true; }));
}
}
编辑:如果您不希望外部使用情况发生变化,那么您将如何使用属性get / set来包装它。将内部observable重命名为其他内容(在本例中为_hasError),并使hasError属性传递基础可观察值:
class TestBase {
public success: KnockoutComputed<boolean>;
public complete: KnockoutComputed<boolean>;
public _hasError: KnockoutObservable<KnockoutComputed<boolean>>;
public get hasError() {
return this._hasError();
}
public set hasError(func: KnockoutComputed<boolean>) {
this._hasError(func);
}
constructor() {
this._hasError = ko.observable(ko.computed<boolean>((): boolean => { return false; }));
this.success = ko.computed<boolean>((): boolean => {
var hasError = this._hasError();
return !hasError() && this.complete();
});
}
}
class Test extends TestBase {
constructor() {
super();
this.hasError = ko.computed<boolean>((): boolean => { return true; });
}
}
答案 1 :(得分:0)
我还没有找到问题的直接答案,但我突然意识到如何改变问题以便找到解决方案。
我没有尝试更改计算机绑定的原始函数,而是在类中存储一个函数指针,并使用计算函数调用该函数。我的解决方案变为:
class MyClass{
public hasError: KnockoutComputed<boolean>;
private errorFn: KnockoutObservable<() => boolean>;
constructor() {
this.errorFn = ko.observable<() => boolean>(null);
this.hasError = ko.computed<boolean>((): boolean => {
if (this.errorFn() != null) {
return this.errorFn()();
}
return false;
});
}
public setErrorFunction(fn: () => boolean): void {
this.errorFn(fn);
}
}
现在我可以通过在setError方法中传入一个不同的函数来重新定义构成错误的内容。我必须使errorFn成为一个observable,以使计算器正确评估并获取可能在新errorFn中的其他依赖项。我希望只是调用this.hasError()会强制重新评估并创建一个新的依赖图,但事实并非如此。