在定义

时间:2017-04-27 16:49:51

标签: knockout.js

我遇到的情况是我在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。

由于

2 个答案:

答案 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()会强制重新评估并创建一个新的依赖图,但事实并非如此。