【问题标题】:Knockout JS binding on computed observable does not work计算的 observable 上的 Knockout JS 绑定不起作用
【发布时间】:2016-05-11 18:27:41
【问题描述】:

我正在尝试向 asp.net MVC 5 网站弹出屏幕添加一个新字段,该屏幕首先使用 Entity Framework 6 代码、Typescript 和 Knockout JS 进行数据绑定。我没有写这个网站。几个月来,我一直在对其进行更改。原来的程序员已经不在公司了。我以前从未使用过这些技术。

新字段是 Web 服务调用的结果。 web 方法确实返回结果。但是,该值不会显示在屏幕上。我的脚本运行并显示所有其他数据。页面显示后返回对 Web 服务的延迟调用。我将提供标记和视图模型代码。非常感谢任何建议。

下面是 HTML 绑定到的计算属性:

this.PredictedValue = ko.pureComputed(() => {
                var age = "";
                var race = "";
                var height = "";
                var studyId = this.Session().Study.PftCentralStudyId();
                var predictedSetName;
                var predictedSetId;
                var gender;
                if (this.StudyTestParameter().HasPredictedValues() == true) {
                    ko.utils.arrayForEach(this.Session().Study.StudyTestTypePredictedSets(),(item: Bll.TestTypePredictedSetVm) => {
                        if (String(item.TestType().Name()) == this.StudyTestParameter().TestType().Name())
                            predictedSetId = item.PredictedSetId();
                    });
                    if (predictedSetId == 0) {
                        return "";
                    }
                    else {
                        var match = ko.utils.arrayFirst(this.Session().PftCentralStudyPredictedSets(),(item: Bll.PftCentralPredictedSetsVm) => {
                            return String(item.Id) == String(predictedSetId)
                        });
                        predictedSetName = match.Name;
                        ko.utils.arrayForEach(this.Session().SessionValues(),(item: SessionValueVm) => {
                            if (String(item.StudySessionParameter().Name()) == "Age")
                                age = String(item.RecordedValue());
                        });
                        ko.utils.arrayForEach(this.Session().SessionValues(),(item: SessionValueVm) => {
                            if (String(item.StudySessionParameter().Name()) == "Race")
                                race = String(item.RecordedValue());
                        });
                        ko.utils.arrayForEach(this.Session().SessionValues(),(item: SessionValueVm) => {
                            if (String(item.StudySessionParameter().Name()) == "Height")
                                height = String(item.RecordedValue());
                        });
                        ko.utils.arrayForEach(this.Session().SessionValues(),(item: SessionValueVm) => {
                            if (String(item.StudySessionParameter().Name()) == "Sex")
                                gender = String(item.RecordedValue());
                        });
                        var promise = this.Session().CalculatePredicted(age, race, gender, height, String(this.StudyTestParameter().PftCentralStudyParameterId()), predictedSetName, studyId);
                        promise.done((data: string) => {
                            return data
                        });
                    }
                }
                else
                    return "";
            });

CalculatePredicted = (age: string, race: string, gender: string, height: string, studySessionParameterId: string, predictedSetName: string, studyId: number) => {

            var deferred = $.Deferred();

            $.ajax({
                url: "/Workflows/CalculatePredicted",
                cache: false,
                data: { age: age, ethnicity: race, gender: gender, height: height, studySessionParameterId: studySessionParameterId, testTypePredictedSetName: predictedSetName, studyId: studyId },
                dataType: "json",
                contentType: "application/json charset=utf-8"
            }).done(data => {
                deferred.resolve(data);
            }).fail((jqXHR) => {
                alert(jqXHR.responseText);
                deferred.reject();
            });
            return deferred;
        }

下面是 HTML。

<div>
                                        Test Values:
                                        <table class="width100pct gridtable">
                                            <tbody data-bind="foreach: TestValues">
                                            <tr>
                                                <td data-bind="text: StudyTestParameter().Name"></td>
                                                <td data-bind="text: RecordedValue"></td>
                                                <td data-bind="text: ATSBestValue"></td>
                                                <td data-bind="text: PredictedValue"></td>
                                            </tr>
                                            </tbody>
                                        </table>
                                    </div>

【问题讨论】:

    标签: javascript jquery asp.net knockout.js typescript


    【解决方案1】:

    您的 promise 对象无法返回您的计算结果。当 promise 完成时,computed 早就返回了 'undefined'。这就是异步调用的本质。考虑在 promise.done() 函数中设置不同的 observable 并绑定到 UI 中的新字段;如果底层字段发生变化,计算函数仍将触发。

    【讨论】:

    • 如果这是问题所在,一旦返回承诺并且计算值发生变化,视图最终不会更新吗?我已经多次使用包含异步调用的计算变量,没有问题..
    • 你不能让 promise 返回计算的值,这是基本的异步内容。您必须在 UI 关联的 Promise 中更新另一个 observable。
    • 我试过了,结果没有变化。我定义了一个新的类属性“FinalPredictedValue = ko.observable();”我将另一种方法更改为: var promise = this.Session().CalculatePredicted(age, race, gender, height, String(this.StudyTestParameter().PftCentralStudyParameterId()), predictedSetName, studyId); promise.done((data: string) => { this.FinalPredictedValue(ko.observable(data)); });
    • 自定义绑定值得尝试吗?我以前从未使用过。
    • @Edward 你不能像这样使用this 来设置属性,它不会是正确的上下文。
    猜你喜欢
    • 2014-03-09
    • 2015-12-03
    • 1970-01-01
    • 2014-11-27
    • 2019-01-23
    • 2014-06-09
    • 1970-01-01
    • 2015-04-05
    • 1970-01-01
    相关资源
    最近更新 更多