0

Когда пользователь нажимает на строку из списка в пользовательском интерфейсе (таблица html tblAllCert), у меня есть событие click, которое позволяет заполнить другой наблюдаемый массив, который должен заполнить вторую таблицу html (tblCertDetails). Мое событие клика срабатывает, я вижу, что данные возвращаются, и я могу видеть данные в наблюдаемом массиве, но мое представление не обновляется.UI не обновляется при обновлении ObservableArray

Ниже приведен обзор последовательности в code-

1. user clicks on row from html table tblAllCert, which fires selectThing method. 
2. In viewmodel code, selectThing passes the row data from the row selected to the GetCertificateDetails(row) method. 
3. GetCertificateDetails(row) method calls getCertDetails(CertificateDetails, source) function on my data service (the data service gets data from a web api). getCertDetails(CertificateDetails, source) function returns an observable array. 
4. once the data is returned to selectThing, CertificateDetails observable array is populated. It does get data to this point. 

Шаг 5 следует обновить пользовательский интерфейс (в частности tblCertDetails HTML таблицу), однако интерфейс не обновляется.

Вот мой view-

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


           <table id="tblCertDetails" border="0" class="table table-hover" width="100%"> 
           <tbody data-bind="foreach: CertificateDetails"> 
            <tr id="Tr1" style="cursor: pointer"> 
             <td> 
              <ul style="width: 100%"> 
               <b>Loan:&nbsp;<span data-bind=" text: loanNum"></span> 
             </td> 
            </tr> 
           </tbody> 

          </table> 

Мой 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 CertificateDetails = ko.observableArray([]); 

    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(); 
    }; 


    var vm = { 
     activate: activate, 
     allCertificates: allCertificates, 
     myCertificates: myCertificates, 
     CertificateDetails: CertificateDetails, 
     title: 'Certificate Approvals', 
     SelectMyCerts: SelectMyCerts, 
     SelectAllCerts: SelectAllCerts, 
     theOptionId: ko.observable(1), 
     serverOptions: serverOptions, 
     serverSelectedOptionID: serverSelectedOptionID, 
     SortUpDownAllCerts: SortUpDownAllCerts, 
     isSelected: isSelected, 
     selectThing: function (row, event) { 
      CertificateDetails = GetCertificateDetails(row); 
      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(row) { 
     var source = { 
      'lwCertID': row.lwCertID, 
      'certType': row.certType, 
     } 
     return CertificateDataService.getCertDetails(CertificateDetails, source); 
    } 

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


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

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

}); 

И releveant выдержка из моих данных Сервис-

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

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

Идеи почему UI не обновляется?

ответ

1

Когда вы используете массивы нокаутов, вы должны изменять содержимое массива, а не ссылку на сам массив. В selectThing, когда вы установили

CertificateDetails = GetCertificateDetails(row); 

нового observableArray, который был назначен CertificateDetails не то же самое, что observableArray KO привязан к вашему столу.

Вы очень близки к решению. В своем обратном вызове AJAX вместо создания нового dataObservableArray и сопоставления с ним вы можете выполнить сопоставление непосредственно в параметре certificateDetailsObservable. ko.mapping.fromJSON должен заменить содержимое массива, связанного с таблицей (вы также избавитесь от назначения в selectThing).

+0

Спасибо ejegg. Это сработало! – Chris

Смежные вопросы