当我更新我的ko.computed时,UI不会更新。我有一个click事件,它触发一个名为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> (<span data-bind=" text: clientNumber"></span>) <span data-bind=" text: borrowBaseCount"></span> Loan(s) </b>
<br />
Collateral Analyst: <span data-bind=" text: userName"></span>
<br />
Certificate: <span data-bind="text: lwCertID"></span> Request Date: <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: <span data-bind="text: LoanNum"></span> (<span data-bind=" text: CurrType"></span>)</b><br />
Collateral Balance: <span data-bind=" text: CollanteralBalance"></span><br />
Sales/Additinal: <span data-bind=" text: SalesAdditions"></span><br />
Discounts: <span data-bind=" text: Discounts"></span><br />
Credit Memos: <span data-bind=" text: CreditMemos"></span><br />
Non AR Cash: <span data-bind=" text: NonARCash"></span><br />
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
以下是使用selectThing方法的viewmodel代码:
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不会更新。我怎样才能解决这个问题?
这是所有代码:
viewmodel:
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> My Certificates
</a>
</li>
<li>
<a id="btnAll" href="#AllCert" data-toggle="tab">
<i class="icon-align-center"></i> All Pending
</a>
</li>
</ul>
<div class="ToolBox" style="height: 30px; width: 100%">
<b> Sort By: </b>
<select id="ddlSortBy" style="margin-top: 0px; height: 24px; width: 160px !important"
data-bind="value: serverSelectedOptionID, options: serverOptions, optionsText: 'name', optionsValue: 'id'">
</select> <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> (<span data-bind=" text: clientNumber"></span>) <span data-bind=" text: borrowBaseCount"></span> Loan(s) </b>
<br />
Collateral Analyst: <span data-bind=" text: userName"></span>
<br />
Certificate: <span data-bind="text: lwCertID"></span> Request Date: <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> (<span data-bind=" text: clientNumber"></span>) <span data-bind=" text: borrowBaseCount"></span> Loan(s) </b>
<br />
Collateral Analyst: <span data-bind=" text: userName"></span>
<br />
Certificate: <span data-bind="text: lwCertID"></span> Request Date: <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: <span data-bind="text: LoanNum"></span> (<span data-bind=" text: CurrType"></span>)</b><br />
Collateral Balance: <span data-bind=" text: CollanteralBalance"></span><br />
Sales/Additinal: <span data-bind=" text: SalesAdditions"></span><br />
Discounts: <span data-bind=" text: Discounts"></span><br />
Credit Memos: <span data-bind=" text: CreditMemos"></span><br />
Non AR Cash: <span data-bind=" text: NonARCash"></span><br />
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
</div>
</td>
</tr>
</table>
你的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可以返回多个证书,因此它将来是一个bug的地方。即使ID是唯一的,我也会使用ko.utils.arrayFirst,因为arrayFilter总是遍历整个数组。