-2

当我更新我的 ko.computed 时,UI 没有更新。我有一个点击事件,它触发了一个名为 selectThing 的方法。selectThing 更新计算,这反过来应该更新我的 UI(它没有)。我是淘汰赛的新手,所以这可能是我缺少关于计算如何工作的概念。这是我对 selectThing 的调用的部分观点:

                                         <tbody data-bind="foreach: myCertificates">
                                        <tr style="cursor: pointer" data-bind="click: $parent.selectThing, css: { highlight: $parent.isSelected() == $data.lwCertID }  ">
                                            <td>
                                                <ul style="width: 100%">
                                                    <b><span data-bind="    text: clientName"></span>&nbsp;(<span data-bind="    text: clientNumber"></span>)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-bind="    text: borrowBaseCount"></span>&nbsp;Loan(s)&nbsp;</b>
                                                    <br />
                                                    Collateral Analyst:&nbsp;<span data-bind="    text: userName"></span>
                                                    <br />
                                                    Certificate:&nbsp;<span data-bind="text: lwCertID"></span>&nbsp;&nbsp;Request&nbsp;Date:&nbsp;<span data-bind="    text: moment(requestDate).format('DD/MMM/YYYY')"></span>
                                            </td>
                                        </tr>
                                    </tbody>

selectThing 应该更新这部分视图-

                     <table id="Table2" style="width: 100%;" border="0">
                     <tr>
                        <td>Length: <span data-bind="text: CertificateDetailsToShow().length"></span>
                            <table id="Table3" border="0" class="table table-hover" width="100%">
                                <tbody data-bind="foreach: CertificateDetailsToShow">
                                    <tr id="Tr1" style="cursor: pointer">
                                        <td>
                                            <ul style="width: 100%">
                                                <b>Loan:&nbsp;<span data-bind="text: LoanNum"></span>&nbsp;(<span data-bind="    text: CurrType"></span>)</b><br />
                                                &nbsp;&nbsp;&nbsp;&nbsp;Collateral Balance:&nbsp;<span data-bind="    text: CollanteralBalance"></span><br />
                                                &nbsp;&nbsp;&nbsp;&nbsp;Sales/Additinal:&nbsp;<span data-bind="    text: SalesAdditions"></span><br />
                                                &nbsp;&nbsp;&nbsp;&nbsp;Discounts:&nbsp;<span data-bind="    text: Discounts"></span><br />
                                                &nbsp;&nbsp;&nbsp;&nbsp;Credit Memos:&nbsp;<span data-bind="    text: CreditMemos"></span><br />
                                                &nbsp;&nbsp;&nbsp;&nbsp;Non AR Cash:&nbsp;<span data-bind="    text: NonARCash"></span><br />

                                        </td>
                                    </tr>
                                </tbody>

                            </table>
                        </td>
                    </tr>
                </table>

这是带有 selectThing 方法的视图模型代码:

         var vm = {
        activate: activate,
        allCertificates: allCertificates,
        myCertificates: myCertificates,
        CertificateDetails: CertificateDetails,
        CertificateDetailsToShow: CertificateDetailsToShow, 
        title: 'Certificate Approvals',
        SelectMyCerts: SelectMyCerts,
        SelectAllCerts: SelectAllCerts,
        theOptionId: ko.observable(1),
        serverOptions: serverOptions,
        serverSelectedOptionID: serverSelectedOptionID,
        SortUpDownAllCerts: SortUpDownAllCerts,
        isSelected: isSelected,
        selectThing: function (row, event) {
            filter = row.lwCertID;
            CertificateDetailsToShow = ko.utils.arrayFilter(CertificateDetails(), function (CertD) {
                        return CertD.CertificateID == filter;
                    });

            isSelected(row.lwCertID);
        }

    };

CertificateDetailsToShow 从 CertificateDetails observablearray 正确填充,但 UI 不会更新。我怎样才能解决这个问题?

这是所有代码:

视图模型:

 define(['services/logger', 'durandal/system', 'durandal/plugins/router', 'services/CertificateDataService'],
function (logger, system, router, CertificateDataService) {
    var allCertificates = ko.observableArray([]);
    var myCertificates = ko.observableArray([]);
    var isSelected = ko.observable();
    var serverSelectedOptionID = ko.observable();
    var filter = ko.observable(0);
    var CertificateDetails = ko.observableArray([]);
    var CertificateDetailsToShow = ko.computed(function () {
        GetCertificateDetails();

        return ko.utils.arrayFilter(CertificateDetails(), function (CertD) {
            return CertD.CertificateID == filter;
        });
    }, this);

    var serverOptions = [
    { id: 1, name: 'Certificate', OptionText: 'lwCertID' },
    { id: 2, name: 'Client Name', OptionText: 'clientName' },
    { id: 3, name: 'Client Number', OptionText: 'clientNumber' },
    { id: 4, name: 'Request Date', OptionText: 'requestDate' },
    { id: 5, name: 'Collateral Analyst', OptionText: 'userName' }
    ];

    var activate = function () {
        // go get local data, if we have it
        return SelectAllCerts(), SelectMyCerts(), CertificateDetailsToShow();
    };


    var vm = {
        activate: activate,
        allCertificates: allCertificates,
        myCertificates: myCertificates,
        CertificateDetails: CertificateDetails,
        CertificateDetailsToShow: CertificateDetailsToShow, 
        title: 'Certificate Approvals',
        SelectMyCerts: SelectMyCerts,
        SelectAllCerts: SelectAllCerts,
        theOptionId: ko.observable(1),
        serverOptions: serverOptions,
        serverSelectedOptionID: serverSelectedOptionID,
        SortUpDownAllCerts: SortUpDownAllCerts,
        isSelected: isSelected,
        selectThing: function (row, event) {
            filter = row.lwCertID;
            CertificateDetailsToShow = ko.utils.arrayFilter(CertificateDetails(), function (CertD) {
                        return CertD.CertificateID == filter;
                    });

            isSelected(row.lwCertID);
        }

    };



    serverSelectedOptionID.subscribe(function () {
        var sortCriteriaID = serverSelectedOptionID();
        allCertificates.sort(function (a, b) {
            var fieldname = serverOptions[sortCriteriaID - 1].OptionText;

            if (a[fieldname] == b[fieldname]) {
                return a[fieldname] > b[fieldname] ? 1 : a[fieldname] < b[fieldname] ? -1 : 0;
            }

            return a[fieldname] > b[fieldname] ? 1 : -1;

        });

    });

    return vm;


    function GetCertificateDetails() {
        return CertificateDataService.getCertDetails(CertificateDetails);
    }

    function SortUpDownAllCerts() {
        allCertificates.sort();
    }


    function SelectAllCerts() {
        return CertificateDataService.getallCertificates(allCertificates);
    }

    function SelectMyCerts() {
        return CertificateDataService.getMyCertificates(myCertificates);
    }

});

数据服务模块:

 define(['services/logger', 'durandal/system'],
function (logger, system) {
    var certificateModel = function (clientID, lwCertID, requestDate, userName, statusDescription, statusCode, statusDesc, ceoUserName, clientName, clientNumber, borrowBaseCount, advRequestCount, certType) {
        var self = this;
        self.clientID = ko.observable(clientID);
        self.lwCertID = ko.observable(lwCertID);
        self.requestDate = ko.observable(requestDate);
        self.userName = ko.observable(userName);
        self.statusDescription = ko.observable(statusDescription);
        self.statusCode = ko.observable(statusCode);
        self.statusDesc = ko.observable(statusDesc);
        self.ceoUserName = ko.observable(ceoUserName);
        self.clientName = ko.observable(clientName);
        self.clientNumber = ko.observable(clientNumber);
        self.borrowBaseCount = ko.observable(borrowBaseCount);
        self.advRequestCount = ko.observable(advRequestCount);
        self.certType = ko.observable(certType);
    };

    var certificateDETAILSModel = function (ToBeProcessedDate, CertType, CertCollID, CertificateID, LoanNumberTypeAndCurrencyCombined, LoanType, CurrType, CollanteralBalance, SalesAdditions,
        CreditMemos, CashRemovals, NonDilutiveAdjustment, Discounts, NonARCash, DilutiveAdjustment, LWCertCollsComments, StatusCode, CertLoanID, Modified, 
        LoanNum, EffectiveDate, RepWireNumber, Advance, ModifiedDate, DDAAccountName, LWCertLoansComments, Comment) {
        var self = this;
        self.ToBeProcessedDate = ko.observable(ToBeProcessedDate);
        self.CertType = ko.observable(CertType);
        self.CertCollID = ko.observable(CertCollID);
        self.CertificateID = ko.observable(CertificateID);
        self.LoanNumberTypeAndCurrencyCombined = ko.observable(LoanNumberTypeAndCurrencyCombined);
        self.LoanType = ko.observable(LoanType);
        self.CurrType = ko.observable(CurrType);
        self.CollanteralBalance = ko.observable(CollanteralBalance);
        self.SalesAdditions = ko.observable(SalesAdditions);
        self.CreditMemos = ko.observable(CreditMemos);
        self.CashRemovals = ko.observable(CashRemovals);
        self.NonDilutiveAdjustment = ko.observable(NonDilutiveAdjustment);
        self.Discounts = ko.observable(Discounts);
        self.NonARCash = ko.observable(NonARCash);
        self.DilutiveAdjustment = ko.observable(DilutiveAdjustment);
        self.LWCertCollsComments = ko.observable(LWCertCollsComments);
        self.StatusCode = ko.observable(StatusCode);
        self.CertLoanID = ko.observable(CertLoanID);
        self.Modified = ko.observable(Modified);
        self.LoanNum = ko.observable(LoanNum);
        self.EffectiveDate = ko.observable(EffectiveDate);
        self.RepWireNumber = ko.observable(RepWireNumber);
        self.Advance = ko.observable(Advance);
        self.ModifiedDate = ko.observable(ModifiedDate);
        self.DDAAccountName = ko.observable(DDAAccountName);
        self.LWCertLoansComments = ko.observable(LWCertLoansComments);
        self.Comment = ko.observable(Comment);
    };

    //var getCertDetails = function (certificateDetailsObservable, source) {
    //    var dataObservableArray = ko.observableArray([]);
    //    $.ajax({
    //        type: "POST",
    //        dataType: "json",
    //        url: "/api/caapproval/CertDtlsByID/",
    //        data: source,
    //        async: false,
    //        success: function (dataIn) {
    //            var newJ = $.parseJSON(dataIn);
    //            ko.mapping.fromJSON(dataIn, {}, dataObservableArray);

    //        },
    //        error: function (error) {
    //            jsonValue = jQuery.parseJSON(error.responseText);
    //            //jError('An error has occurred while saving the new part source: ' + jsonValue, { TimeShown: 3000 });
    //        }

    //    });
    //    return dataObservableArray;
    //}
    var getCertDetails = function (certificateDetailsObservable) {
        var dataObservableArray = ko.observableArray([]);
        var newJ;
        $.ajax({
            type: "POST",
            dataType: "json",
            url: "/api/caapproval/CertDtlsByID/",
            data: '{}',
            async: false,
            success: function (dataIn) {
                newJ = $.parseJSON(dataIn);

                certificateDetailsObservable([]);

                newJ.forEach(function (p) {
                    var certificateDtls = new certificateDETAILSModel(p.toBeProcessedDate, p.certType, p.certCollID, p.certificateID,
                        p.loanNumberTypeAndCurrencyCombined, p.loanType, p.currType, p.collanteralBalance, p.salesAdditions,
                        p.creditMemos, p.cashRemovals, p.nonDilutiveAdjustment, p.discounts, p.nonARCash, p.dilutiveAdjustment, p.lWCertCollsComments, p.statusCode, p.certLoanID, p.modified,
                        p.loanNum, p.effectiveDate, p.repWireNumber, p.advance, p.modifiedDate, p.dDAAccountName, p.lWCertLoansComments, p.comment);
                    certificateDetailsObservable.push(certificateDtls);
                });


            },
            error: function (error) {
                jsonValue = jQuery.parseJSON(error.responseText);
                //jError('An error has occurred while saving the new part source: ' + jsonValue, { TimeShown: 3000 });
            }

        });
        return certificateDetailsObservable(newJ);
    }

        var getallCertificates = function (CertificatesObservable) {
            $.getJSON('/api/caapproval', function (data) {

                CertificatesObservable([]);
                data.forEach(function (p) {
                    var certificate = new certificateModel(p.clientID, p.lwCertID, p.requestDate, p.userName, p.statusDescription, p.statusCode, p.statusDesc, p.ceoUserName, p.clientName, p.clientNumber, p.borrowBaseCount, p.advRequestCount, p.certType);
                    CertificatesObservable.push(certificate);
                });
                return CertificatesObservable(data);
            });
        }

        var getMyCertificates = function (CertificatesObservable) {
            $.getJSON('/api/caapproval/myCert', function (data) {

                CertificatesObservable([]);
                data.forEach(function (p) {
                    var certificate = new certificateModel(p.clientID, p.lwCertID, p.requestDate, p.userName, p.statusDescription, p.statusCode, p.statusDesc, p.ceoUserName, p.clientName, p.clientNumber, p.borrowBaseCount, p.advRequestCount, p.certType);
                    CertificatesObservable.push(certificate);
                });
                return CertificatesObservable(data);
            });
        }

    var dataservice = {
        getallCertificates: getallCertificates,
        getMyCertificates: getMyCertificates,
        getCertDetails: getCertDetails
    };
    return dataservice;

});

看法 :

 <section>

<br />
<br />
<br />
<table border="0" style="width: 100%">
    <tr>
        <td style="width: 50%">
            <h2 data-bind="text: title"></h2>
            <ul class="nav nav-tabs" style="width: 100%">
                <li class="active">
                    <a id="btnMyCert" href="#MyCert" data-toggle="tab">
                        <i class="icon-align-center"></i>&nbsp;&nbsp;My Certificates&nbsp;
                    </a>
                </li>
                <li>
                    <a id="btnAll" href="#AllCert" data-toggle="tab">
                        <i class="icon-align-center"></i>&nbsp;&nbsp;All Pending&nbsp;
                    </a>
                </li>

            </ul>
            <div class="ToolBox" style="height: 30px; width: 100%">
                <b>&nbsp;&nbsp;Sort By:&nbsp;</b>
                <select id="ddlSortBy" style="margin-top: 0px; height: 24px; width: 160px !important"
                    data-bind="value: serverSelectedOptionID, options: serverOptions, optionsText: 'name', optionsValue: 'id'">
                </select>&nbsp;&nbsp;<img data-bind="click: SortUpDownAllCerts" src="/Content/images/updownarrow.bmp" style="padding-bottom: 4px; cursor: pointer; vertical-align: middle;" />
            </div>

            <div class="tab-content">
                <div id="MyCert" class='tab-pane active' style="height: 400px; width: 100%; overflow-x: hidden; overflow-y: auto;">
                    <div class="btn-group">
                    </div>
                    <table id="tblCert" style="width: 100%;" border="0">
                        <tr>
                            <td>
                                <table id="tblMyCert" border="0" class="table table-hover" width="100%">
                                    <tbody data-bind="foreach: myCertificates">
                                        <tr style="cursor: pointer" data-bind="click: $parent.selectThing, css: { highlight: $parent.isSelected() == $data.lwCertID }  ">
                                            <td>
                                                <ul style="width: 100%">
                                                    <b><span data-bind="    text: clientName"></span>&nbsp;(<span data-bind="    text: clientNumber"></span>)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-bind="    text: borrowBaseCount"></span>&nbsp;Loan(s)&nbsp;</b>
                                                    <br />
                                                    Collateral Analyst:&nbsp;<span data-bind="    text: userName"></span>
                                                    <br />
                                                    Certificate:&nbsp;<span data-bind="text: lwCertID"></span>&nbsp;&nbsp;Request&nbsp;Date:&nbsp;<span data-bind="    text: moment(requestDate).format('DD/MMM/YYYY')"></span>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                            </td>
                        </tr>
                    </table>
                </div>
                <div id="AllCert" class='tab-pane' style="height: 400px; width: 100%; overflow-x: hidden; overflow-y: auto;">
                    <table id="Table1" style="width: 100%;" border="0">
                        <tr>
                            <td>
                                <table id="tblAllCert" border="0" class="table table-hover" width="100%">
                                    <tbody data-bind="foreach: allCertificates">
                                        <tr id="AllCertRow" style="cursor: pointer" data-bind="click: $parent.selectThing, css: { highlight: $parent.isSelected() == $data.lwCertID }">
                                            <td>
                                                <ul style="width: 100%">

                                                    <b><span data-bind="    text: clientName"></span>&nbsp;(<span data-bind="    text: clientNumber"></span>)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span data-bind="    text: borrowBaseCount"></span>&nbsp;Loan(s)&nbsp;</b>
                                                    <br />
                                                    Collateral Analyst:&nbsp;<span data-bind="    text: userName"></span>
                                                    <br />
                                                    Certificate:&nbsp;<span data-bind="text: lwCertID"></span>&nbsp;&nbsp;Request&nbsp;Date:&nbsp;<span data-bind="    text: moment(requestDate).format('DD/MMM/YYYY')"></span>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                            </td>
                        </tr>
                    </table>
                </div>
            </div>
        </td>
        <td style="width: 50%">
            <br /><br /><br /><br /><br />
            <div id="Div1" class='tab-pane' style="height: 400px; width: 100%; overflow-x: hidden; overflow-y: auto;">
                <table id="Table2" style="width: 100%;" border="0">
                     <tr>
                        <td>Length: <span data-bind="text: CertificateDetailsToShow().length"></span>
                            <table id="Table3" border="0" class="table table-hover" width="100%">
                                <tbody data-bind="foreach: CertificateDetailsToShow">
                                    <tr id="Tr1" style="cursor: pointer">
                                        <td>
                                            <ul style="width: 100%">
                                                <b>Loan:&nbsp;<span data-bind="text: LoanNum"></span>&nbsp;(<span data-bind="    text: CurrType"></span>)</b><br />
                                                &nbsp;&nbsp;&nbsp;&nbsp;Collateral Balance:&nbsp;<span data-bind="    text: CollanteralBalance"></span><br />
                                                &nbsp;&nbsp;&nbsp;&nbsp;Sales/Additinal:&nbsp;<span data-bind="    text: SalesAdditions"></span><br />
                                                &nbsp;&nbsp;&nbsp;&nbsp;Discounts:&nbsp;<span data-bind="    text: Discounts"></span><br />
                                                &nbsp;&nbsp;&nbsp;&nbsp;Credit Memos:&nbsp;<span data-bind="    text: CreditMemos"></span><br />
                                                &nbsp;&nbsp;&nbsp;&nbsp;Non AR Cash:&nbsp;<span data-bind="    text: NonARCash"></span><br />

                                        </td>
                                    </tr>
                                </tbody>

                            </table>
                        </td>
                    </tr>
                </table>
            </div>

        </td>
    </tr>



</table>

4

1 回答 1

1

selectThing不应该写信给 ko.computed。它们应该是只读的(除非另有说明)。因此,您的函数所做的是var CertificateDetailsToShow用静态数据覆盖,因此它不再可观察,因此在更新 UI 时淘汰不会考虑它。

这就是您错过概念并回答您的问题的方式。

要解决此问题,要么创建var CertificateDetailsToShow一个 ko.observable 并在其中添加selectThing新值:CertificateDetailsToShow( certificateID )或者因为您已经isSelected(row.lwCertID)通过定义过滤器将其保存在 ko.computed 中使用它(并且不要覆盖它):

var filter = isSelected()
return ko.utils.arrayFilter(CertificateDetails(), function (CertD) {
            return CertD.CertificateID == filter;
       });

取决于你需要什么。同样寻找你的价值两次也不是最优的。并且 ko.utils.arrayFilter 可以返回多个证书,因此它是将来出现错误的地方。即使 ID 是唯一的,我也会选择 ko.utils.arrayFirst,因为 arrayFilter 总是遍历整个数组。

于 2013-07-26T17:55:21.547 回答