2016-06-30 9 views
0

私はag-gridのAngular 2無限スクロールを行っており、データ部分をsetRowDataと同期させる問題があります。 重複問題は、最初のスクロールイベントハンドラが と呼び出された後に発生します(スクロール前に最初にロードされたデータの2番目の部分を取得するため)、ページのデータのHTTP要求が 部分が送信されます。現在、非同期HTTP要求のみが使用可能であるため(同期は非推奨)、 HTTP応答を受信する前にsetRowDataに制御が渡されます。その結果、古い行のデータは、グリッドを投入するために使用されます。 および第1の&第2ページは同じように見えます。 setRowDataの実行をブロックしようとする試みは、HTTPレスポンスUNTILが到着しましたが、失敗しました。 setIntervals()& setTimeout()はブロックされず、whileループはHTTP要求/応答を含むすべてのブロックをブロックしました。 後者の場合、このフラグはResponseが処理された後で初めて に更新されるため、ループ出口の条件が満たされないため、実行は永久に停止します。 HTTP要求を同期させることもできません。 ベローは、HTTP関数のコードです:ag-grid無限スクロールの同期に関する問題

private getDataPortionFromServer = function(startRow: number, endRow: number, firstTime: boolean) { 
     console.log('getDataPortionFromServer: lastEndRow = ' + this.lastEndRow + ', current endRow' + endRow); 
     if (this.lastEndRow == endRow) { 
      console.log('getDataPortionFromServer: exiting to avopid dup call'); 
      return; 
     } 
     var url: string = ...; //co 
    function getDataSynchronously(url, callback) { 
     var httpRequest = new XMLHttpRequest(); 
     httpRequest.open('GET', url, true); 
     httpRequest.setRequestHeader('Accept','*/*'); 
     httpRequest.setRequestHeader('Content-Type','application/json'); 
     sac.stillRetrieveing = true; 
     httpRequest.onreadystatechange = function() { 
     if (httpRequest.readyState == 4 && httpRequest.status == 200) { 
      if (typeof callback == "function") { 
      // apply() sets the meaning of "this" in the callback 
      callback.apply(httpRequest); 
      } 
     } 
     } 
     httpRequest.send(); 
    } 
    getDataSynchronously(
     url, 
     function() { 
     console.log('Rrocessing Response : ' + '[' + new Date().toUTCString() + '] '); 
     var hs = this.responseText; 
     //doing something with data in this.responseText; 
       var rd = sac.fitInColumnDefinition(httpResult[0].data); // 'rd' is actual row data for a page 
     stillRetrieveing = false; // !!! this is the flag; if false, execution may continue 
           // otherwise execution should wait until stillRetrieveing = false 

     if (firstTime) { //1st portion of Row Data before any scrolling 
     setRowData(rd); //1st time no issue, problem comes when scrolling starts 
     } 
     sac.rowData = rd; 
     } 
); 
} 

//ここでsetRowDataです:

private setRowData(allOfTheData) { 
    var sac: SampleAppComponent; 
    sac = this; 
    var dataSource = { 
     rowCount: null, // behave as infinite scroll 
     pageSize: sac.pageSize, 
     overflowSize: sac.pageSize, 
     maxConcurrentRequests: 2, 
     maxPagesInCache: 2, 

     getRows: (params:any) => { 
     console.log('asking for ' + params.startRow + ' to ' + params.endRow); 

     sac.getDataPortionFromServer(params.startRow, params.endRow, false); // !!! asynchronous, comes immediately to 
                       // next line: allOfTheData = sac.rowData 
                       // without waiting for fresh row data 

/* 
Realy need here some blocking mechanism that would allow: 
a) block execution before the next line "allOfTheData = sac.rowData;" 
b) during blocking, be able to observe somehow value of 'stillRetrieveing' flag and detect when it changes 
    (something like volatile in JAVA) 
c) never exit blocking unless stillRetrieveing == false 
*/ 

     setTimeout(function() { 
      allOfTheData = sac.rowData; 
          // take a slice of the total rows 
      var dataAfterSortingAndFiltering = sac.sortAndFilter(params.sortModel, params.filterModel, allOfTheData); 

          // if on or after the last page, work out the last row. 
      var lastRow = parseInt(sac.rowsReturned); 
          // call the success callback 
      params.successCallback(dataAfterSortingAndFiltering, lastRow); 

      }, 500); 

     } //getRows: function (params) 
    }; //var dataSource 

    this.gridOptions.api.setDatasource(dataSource); 
} 

大幅に任意のアドバイスや手がかりを感謝することでしょう。

答えて

0

行レンダラーコールバックをHTTPコールバックに直接配置することで解決しました。コードをかなり修正しなければならなかったが、それが私がそれを行うことができる唯一の方法だ。プロミスやオブザーバブルは私にとってはうまくいかなかった。