2013-07-26 83 views
-2

更新當我更新我的ko.computed時,用戶界面不會更新。我有一個點擊事件觸發了一個名爲selectThing的方法。 selectThing更新計算,這反過來應該更新我的用戶界面(它不)。我是淘汰賽的新手,所以這可能是我缺少計算機工作原理的概念。這是我與調用selectThing視圖的一部分:用戶界面不與ko.utils.arrayFilter

          <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> 

+6

請將您的示例代碼降至最低,以顯示您的問題! – nemesv

回答

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總是遍歷整個數組。

+0

正如所建議的,我擺脫了selectThing中的計算,並將篩選器更改爲篩選器(row.lwCertID),並且效果很好。謝謝Wojciech,這讓我走了! – Chris