触发计算属性更新

时间:2016-11-29 11:33:29

标签: typescript knockout.js

我试图强制将计算属性更新从viewmodel更新到UI。但是我只获得初始值而不是任何其他值。变异属性失败,因为它不是一个函数。

网站

<script src="../../libraries/knockout-3.4.1.js"></script>
<input id="nameInput" data-bind="value: processName" type="text"/>
<input id="nodetotalInput" data-bind="value: processNodeCount" type="text"/>

查看模型

export class ProcessViewModel {
    public processName: KnockoutObservable<string>;
    public processNodeCount: KnockoutObservable<number>;

    constructor() {
        try {
            this.testService = new Test.TestService();

            this.setBindings();
        }
        catch (e) {
            console.log(e);
        }
    }

    public setBindings(): void {
        this.processName = ko.computed<string>(
            function() { processViewModel.isLoaded() ? processViewModel.testService.flowModel.process.name : ""; }
        );
        this.processNodeCount = ko.computed<number>(
            function() { processViewModel.isLoaded() ? processViewModel.testModel.nodeCount() : 0; }
        );
    }

    public isLoaded(): boolean {
        return this.testService.isLoaded();
    }

    public refreshProcessDetails() {
        try {
            let message: string = "IsLoaded" + this.isLoaded();
            console.log(message);

            /** attempts at triggering an update */
            this.processName();
            this.processName.valueHasMutated(); // fails because it's not a function

            this.processNodeCount();
        }
        catch (e) {
            console.log(e);
        }
    }
}

结合

declare var processViewModel: Process.ProcessViewModel;

window.onload = () => {
    processViewModel = new Process.ProcessViewModel();
    processViewModel.setBindings();
    ko.applyBindings(processViewModel);
}

从this.refreshProcessDetails();

调用this.processName.valueHasMutated()时出现以下错误

stack:&#34; TypeError:this.processName.valueHasMutated不是

中的函数\ n

1 个答案:

答案 0 :(得分:3)

valueHasMutated是一种只有普通观察者才有的方法。计算的可观察者没有这种方法。这主要是因为valueHasMutated没有按照您的想法行事。它不会在您调用它的observable中触发更新,而是在订阅observables中触发下游更新,因此它不会在这里帮助您。在这种情况下,如果这样做,它会告诉HTML绑定更新,但不会更改processName的值,因此绑定不会做任何事情。

通常,除了更改它所依赖的observable之外,无法触发对计算的observable的更新。相反,您的计算机可观察应该依赖于某个地方(最好)的另一个可观察对象,或者您应该自己手动写入一个可观察对象(如果必须)。要做到这一点:

  1. 如果可以的话,让processViewModel.testService.flowModel.process.name正在改变的部分(例如进程名称,或进程本身,如果要更改等)可观察,以便计算的将自动更新什么时候。
  2. 或者,根本没有计算机。将processName和processNodeCount保留为普通的observable,并在调用refreshProcessDetails时,将正确的值写入其中。
  3. 存在用于自动保持数据模型始终同步的计算机。你必须提交(全部使用observables)或自己动手(手动更新普通的observables),你不能保持在中间。

    请注意,如果你选择2,你会失去很多(全部?)的Knockout值。正确的&#39;方法做Knockout是保持你的应用程序的大部分(这里的字段,以及这依赖的模型中的字段)可观察,以便一切神奇地起作用。使用Knockout的代码部分越大,效果越好 - 缩小它意味着Knockout宁愿为您做更多的手工工作。