2017-01-23 38 views
1

我正在複製將網格視圖示例放入表示表的對象而不是匿名函數。我不明白爲什麼它會在連接到模擬服務器時給我的標題中的錯誤,因爲它是完全相同的代碼。Ag-grid viewport:無法讀取未定義的屬性'bind'

這似乎並沒有工作代碼:

function ViewportDatasource(mockServer) { 
     this.mockServer = mockServer; 
     this.connectionId = this.mockServer.connect(this.eventListener.bind(this)); 
    } 

    ViewportDatasource.prototype.eventListener = function (event) { 
     switch (event.eventType) { 
      case 'rowCountChanged': 
       this.onRowCountChanged(event); 
       break; 
      case 'rowData': 
       this.onRowData(event); 
       break; 
      case 'dataUpdated': 
       this.onDataUpdated(event); 
       break; 
     } 
    }; 

這裏是整個對象:

function WatcherTable($rootScope,$scope, $http) { 

    this.FIELD_KEY_ID = "id"; 
    this.FIELD_KEY_ISSUER_SHORT_DESC= "isd"; 
    this.FIELD_KEY_ISSUER = "iss"; 
    this.FIELD_KEY_CUSIP = "cus"; 
    this.FIELD_KEY_ISIN = "isin"; 
    this.FIELD_KEY_BOARD_LABEL = "lbl"; 
    this.FIELD_KEY_IND_SECT_LABEL = "isl"; 
    this.FIELD_KEY_CURR="cur" 

    this.FIELD_KEY_BEST_BID_SIZE = "bBidSz"; 
    this.FIELD_KEY_BEST_BID_PRICE = "bBidPrc"; 
    this.FIELD_KEY_BEST_ASK_PRICE = "bAskPrc"; 
    this.FIELD_KEY_BEST_ASK_SIZE = "bAskSz"; 
    this.FIELD_KEY_BEST_BID_SPREAD = "bBidSpd"; 
    this.FIELD_KEY_BEST_ASK_SPREAD = "bAskSpd"; 

    this.FIELD_KEY_ORDER_BID_SIZE = "oBidSz"; 
    this.FIELD_KEY_ORDER_BID_PRICE = "oBidPrc"; 
    this.FIELD_KEY_ORDER_ASK_PRICE = "oAskPrc"; 
    this.FIELD_KEY_ORDER_ASK_SIZE = "oAskSz"; 
    this.FIELD_KEY_ORDER_BID_SPREAD = "oBidSpd"; 
    this.FIELD_KEY_ORDER_ASK_SPREAD = "oAskSpd"; 

    this.headerMyOrder="ORDER"; 
    this.headerMyBidOrder="BID ORDER"; 
    this.headerMyAskOrder="ASK ORDER"; 


    this.cols = [{ 
     headerName : "Security Info", 
     marryChildren : true, 
     children : [{ 
      headerName : "Issuer Short Desc.", 
      field : this.FIELD_KEY_ISSUER_SHORT_DESC, 

      //width : 0, 
      //hide : true 
     }, 
     { 
      headerName : "Industry Sector Label", 
      field : this.FIELD_KEY_IND_SECT_LABEL, 
      //width : 80, 
      filter: 'set', 
      filterParams: { values: ['Advertising', 'Aerospace/Defense', 'Agriculture', 'Airlines', 'Apparel', 'Auto Manufacturers', 'Auto Parts&Equipment', 'Banks', 'Basic Materials', 'Beverages', 'Biotechnology', 'Building Materials', 'Chemicals', 'Coal', 'Commercial Services', 'Communications', 'Computers', 'Consumer, Cyclical', 'Consumer, Non-cyclical', 'Cosmetics/Personal Care', 'Distribution/Wholesale', 'Diversified', 'Electrical Compo&Equip', 'Electronics', 'Energy', 'Energy-Alternate Sources', 'Engineering&Construction', 'Entertainment', 'Machinery-Constr&Mining', 'Household Products/WaresIndustrial', 'Insurance', 'Internet', 'Investment Companies', 'Iron/Steel', 'Kangaroos', 'Leisure Time', 'Lodging', 'Machinery-Constr&Mining', 'Machinery-Diversified', 'Media', 'Metal Fabricate/Hardware', 'Mining', 'Miscellaneous Manufactur', 'Multi-National', 'Office Furnishings', 'Office/Business ', 'Oil&Gas', 'Oil&Gas Services', 'Packaging&Containers', 'Pharmaceuticals', 'Pipelines', 'Real Estate', 'Regional(state/provnc)', 'REITS', 'Retail', 'Savings&Loans'], 
          newRowsAction: 'keep'}, 
      }, 
     { 
      headerName : "Board Label", 
      field : this.FIELD_KEY_BOARD_LABEL, 
      //width : 80, 
      filter: 'text', 
      filterParams: { apply: true } 

     }, { 
      headerName : "CUSIP", 
      field : this.FIELD_KEY_CUSIP, 
      //width : 150, 
      //suppressFilter: true 
     }, 
     { 
      headerName : "ISIN", 
      field : this.FIELD_KEY_ISIN, 
      //width : 150, 
      //suppressFilter: true 
     }, 
     { 
      headerName : "Currency", 
      field : this.FIELD_KEY_CURR, 
      //width : 150, 
      //suppressFilter: true 
     } 
     ]}, 
     { 
     headerName : "Best", 
     marryChildren : true, 

     children : [ { 
      headerName : "Bid Size", 
      pinned: 'right', 
      field : this.FIELD_KEY_BEST_BID_SIZE, 
      cellStyle: {'border-left': '1px solid #E82043', 'color':'#E82043', 'font-weight':'bold', 'text-align':'right'}, 
      cellRenderer: BidRenderer, 
      filter:'number', 


      //width : 125, 
      //suppressFilter: true 
     }, { 
      headerName : "Bid Price", 
      pinned: 'right', 
      field : this.FIELD_KEY_BEST_BID_PRICE, 
      cellStyle: {'border-right': '1px solid #E82043', 'color':'#E82043', 'font-weight':'bold', 'text-align':'right'}, 
      //cellRenderer: 'animateShowChange', 
      cellFormatter: numberFormatter, 
      cellRenderer: BidRenderer, 
      width : 125, 
      filter:'number', 


      //suppressFilter: true 
     }, 
     { 
      headerName : "Ask Price", 
      pinned: 'right', 
      field : this.FIELD_KEY_BEST_ASK_PRICE, 
      //cellRenderer: 'animateShowChange', 
      cellFormatter: numberFormatter, 
      cellRenderer: AskRenderer, 
      cellStyle: {'color':'#19B092', 'font-weight':'bold', 'text-align':'right'}, 
      filter:'number', 
      //width : 125, 
      //suppressFilter: true 
     }, 
     { 
      headerName : "Ask Size", 
      pinned: 'right', 
      field : this.FIELD_KEY_BEST_ASK_SIZE, 
      cellStyle: {'border-right': '1px solid #19B092', 'color':'#19B092', 'font-weight':'bold', 'text-align':'right'}, 
      cellRenderer: AskRenderer, 
      filter:'number', 
      //width : 125, 
      //suppressFilter: true 
     } ] 
    } ]; 


    //definizione della tabella//// rowModelType: 'virtual', rowModelType: 'pagination', 



    this.table = { 
      showPrice: true, 
      showSpread: true, 
      orderSize: 0, 
      orderFilter: '', 
      enableServerSideFilter: true, 
      enableServerSideSorting: true, 
      sortingOrder: ['desc','asc',null], 
      enableColResize : true, 
      debug : true, 
      rowSelection : 'multiple', 
      rowDeselection : true, 
      columnDefs : this.cols, 
      rowModelType : 'viewport', 
      headerHeight: 20, 
      rowHeight: 20, 
      viewportRowModelPageSize:30, 
      viewportRowModelBufferSize: 15,   
      suppressColumnVirtualisation: true, 
      suppressMenuColumnPanel: true, 
      onCellDoubleClicked: WatcherTable.prototype.onCellDoubleClicked.bind(this,$rootScope),   
      getContextMenuItems: WatcherTable.prototype.getContextMenuItems.bind(this,$rootScope), 
      getMainMenuItems: WatcherTable.prototype.getMainMenuItems.bind(this, $rootScope), 
      getRowNodeId: function (data) { 
       // the code is unique, so perfect for the id 
       return data.isin; 
      }, 
      onGridReady:setRowData($http) 
    }; 

    function numberFormatter(params) { 
     if (typeof params.value === 'number') { 
      return params.value.toFixed(4); 
     } else { 
      return params.value; 
     } 
    } 



    function BidRenderer() {} 

    BidRenderer.prototype.init = function(params) { 
     // create the cell 
     this.eGui = document.createElement('div'); 
     this.eGui.innerHTML = '<div></div>'; 

     // set value into cell 
     this.eValue = this.eGui.querySelectorAll('div')[0]; 
     this.eValue.innerHTML = params.valueFormatted ? params.valueFormatted : params.value; 

    }; 

    // gets called once when grid ready to insert the element 
    BidRenderer.prototype.getGui = function() { 
     return this.eGui; 
    }; 

    // gets called whenever the user gets the cell to refresh 
    BidRenderer.prototype.refresh = function(params) { 
     // set value into cell again 
     this.eGui.innerHTML = '<div class="bid"></div>'; 
     this.eValue = this.eGui.querySelectorAll('div')[0]; 
     this.eValue.innerHTML = params.valueFormatted ? params.valueFormatted : params.value; 

    }; 

    function AskRenderer() {} 

    AskRenderer.prototype.init = function(params) { 
     // create the cell 
     this.eGui = document.createElement('div'); 
     this.eGui.innerHTML = '<div></div>'; 

     // set value into cell 
     this.eValue = this.eGui.querySelectorAll('div')[0]; 
     this.eValue.innerHTML = params.valueFormatted ? params.valueFormatted : params.value; 

    }; 

    // gets called once when grid ready to insert the element 
    AskRenderer.prototype.getGui = function() { 
     return this.eGui; 
    }; 

    // gets called whenever the user gets the cell to refresh 
    AskRenderer.prototype.refresh = function(params) { 
     // set value into cell again 
     this.eGui.innerHTML = '<div class="ask"></div>'; 
     this.eValue = this.eGui.querySelectorAll('div')[0]; 
     this.eValue.innerHTML = params.valueFormatted ? params.valueFormatted : params.value; 
    }; 

    // client code (ie your code) will call this constructor, pass in whatever you need for the 
    // viewport to do it's job 
    function ViewportDatasource(mockServer) { 
     this.mockServer = mockServer; 
     this.connectionId = this.mockServer.connect(this.eventListener.bind(this)); 
    } 

    // gets called by the grid, tells us what rows the grid is displaying, so time for 
    // us to tell the server to give us the rows for that displayed range 
    ViewportDatasource.prototype.setViewportRange = function (firstRow, lastRow) { 
     this.mockServer.setViewportRange(this.connectionId, firstRow, lastRow); 
    }; 

    // gets called by the grid, provides us with the callbacks we need 
    ViewportDatasource.prototype.init = function (params) { 
     this.params = params; 
    }; 

    // gets called by grid, when grid is destroyed or this datasource is swapped out for another one 
    ViewportDatasource.prototype.destroy = function() { 
     this.mockServer.disconnect(this.connectionId); 
    }; 

    // manages events back from the server 
    ViewportDatasource.prototype.eventListener = function (event) { 
     switch (event.eventType) { 
      case 'rowCountChanged': 
       this.onRowCountChanged(event); 
       break; 
      case 'rowData': 
       this.onRowData(event); 
       break; 
      case 'dataUpdated': 
       this.onDataUpdated(event); 
       break; 
     } 
    }; 

    // process rowData event 
    ViewportDatasource.prototype.onRowData = function (event) { 
     var rowDataFromServer = event.rowDataMap; 
     this.params.setRowData(rowDataFromServer); 
    }; 

    // process dataUpdated event 
    ViewportDatasource.prototype.onDataUpdated = function (event) { 
     var that = this; 
     event.changes.forEach(function (change) { 
      var rowNode = that.params.getRow(change.rowIndex); 
      // if the rowNode is missing, it means the grid is not displaying that row. 
      // if the data is missing, it means the rowNode is there, but that data has not 
      // loaded into it yet, so to early to set delta changes. 
      if (!rowNode || !rowNode.data) { 
       return; 
      } 
      // rowNode.data[change.columnId] = change.newValue; 
      // this is a trick, it gets the row to refresh 
      rowNode.setDataValue(change.columnId, change.newValue); 
     }); 
    }; 

    // process rowCount event 
    ViewportDatasource.prototype.onRowCountChanged = function (event) { 
     var rowCountFromServer = event.rowCount; 
     // this will get the grid to make set the height of the row container, so we can scroll vertically properly 
     this.params.setRowCount(rowCountFromServer); 
    }; 

    function setRowData($http) { 
     // set up a mock server - real code will not do this, it will contact your 
     // real server to get what it needs 
     var mockServer = new MockServer(); 
     $http.get('data.json').then(function(response){ 
      mockServer.init(response.data); 
     }); 

     var viewportDatasource = new ViewportDatasource(mockServer); 
     table.api.setViewportDatasource(viewportDatasource); 
     // put the 'size cols to fit' into a timeout, so that the scroll is taken into consideration 
     setTimeout(function() { 
      table.api.sizeColumnsToFit(); 
     }, 100); 
    } 

    // setup the grid after the page has finished loading 
    /* document.addEventListener('DOMContentLoaded', function() { 
     var gridDiv = document.querySelector('#liveStreamExample'); 
     new agGrid.Grid(gridDiv, table); 

     // do http request to get our sample data - not using any framework to keep the example self contained. 
     // you will probably use a framework like JQuery, Angular or something else to do your HTTP calls. 
     var httpRequest = new XMLHttpRequest(); 
     httpRequest.open('GET', 'data.json'); 
     httpRequest.send(); 
     httpRequest.onreadystatechange = function() { 
      if (httpRequest.readyState == 4 && httpRequest.status == 200) { 
       var httpResponse = JSON.parse(httpRequest.responseText); 
       setRowData(httpResponse); 
      } 
     }; 
    });*/ 

}; 

WatcherTable.prototype.getContextMenuItems = function ($rootScope,params){ 
    var result= [{name:"Show Book", action:WatcherTable.prototype.changeBookSubscription.bind(this,$rootScope,params.node.data)}]; 

    return result; 
} 

WatcherTable.prototype.onCellDoubleClicked = function ($rootScope,params){ 
    $rootScope.$broadcast("changeBookSubscription",{instrkey:params.data.cus+"."+params.data.isin,boardLabel:params.data.isd+" "+params.data.lbl}); 
    if(params.colDef.field.indexOf("bBid")>-1){ 
     $rootScope.$broadcast("showHitDialog",params); 
     log("Show hit dialog"); 
     console.log(params); 
    } 
    else if(params.colDef.field.indexOf("bAsk")>-1){ 
     $rootScope.$broadcast("showLiftDialog",params); 
     log("Show lift dialog"); 
     console.log(params); 
    } 
} 

WatcherTable.prototype.changeBookSubscription = function ($rootScope,data) { 
    $rootScope.$broadcast("changeBookSubscription",{instrkey:data.cus+"."+data.isin,boardLabel:data.isd+" "+data.lbl}); 
} 

WatcherTable.prototype.getMainMenuItems = function($rootScope, params){ 
    var prcCols=["bBidPrc","bAskPrc","oBidPrc","oAskPrc"]; 
    var spdCols=["bBidSpd","bAskSpd","oBidSpd","oAskSpd"]; 
    var menuItems= [ 
     {name:'Show Price', 
      action:function(){ 
         params.columnApi.setColumnsVisible(prcCols, !params.api.gridCore.gridOptions.showPrice); 
         params.api.gridCore.gridOptions.showPrice= !params.api.gridCore.gridOptions.showPrice;  
        }, 
      checked: params.api.gridCore.gridOptions.showPrice 
      }, 
     {name:'Show Spread', 
     action:function(){ 
        params.columnApi.setColumnsVisible(spdCols, !params.api.gridCore.gridOptions.showSpread); 
        params.api.gridCore.gridOptions.showSpread= !params.api.gridCore.gridOptions.showSpread;   
       }, 
     checked: params.api.gridCore.gridOptions.showSpread 
     }, 
     { 
      name:'Orders', 
       subMenu:[ 
        {name:'Live Orders Only', 
         action:function(){ 
         if (params.api.gridCore.gridOptions.orderFilter==='live'){ 
          params.api.gridCore.gridOptions.orderFilter=''; 
          //TODO filter 
         } 
         else {params.api.gridCore.gridOptions.orderFilter='live'; 
          //TODO filter 
         } 

        }, checked:(params.api.gridCore.gridOptions.orderFilter==='live')}, 
        {name:'My Orders Only',  action:function(){ 
         if (params.api.gridCore.gridOptions.orderFilter==='mine'){ 
          params.api.gridCore.gridOptions.orderFilter=''; 
          //TODO filter 
         } 
         else {params.api.gridCore.gridOptions.orderFilter='mine'; 
          //TODO filter 
         } 

        }, checked:(params.api.gridCore.gridOptions.orderFilter==='mine')}, 
        {name:'My Firm\'s Orders Only', action:function(){ 
         if (params.api.gridCore.gridOptions.orderFilter==='firm'){ 
          params.api.gridCore.gridOptions.orderFilter=''; 
          //TODO filter 
         } 
         else {params.api.gridCore.gridOptions.orderFilter='firm'; 
          //TODO filter 
         } 

        }, checked:(params.api.gridCore.gridOptions.orderFilter==='firm')}, 
       ] 
     }, 
     {name: 'Size ...', action: function() { 

      console.log(params.api.gridCore.gridOptions.orderSize); 
      $rootScope.$broadcast("orderSizeDialog",{size:parseInt(params.api.gridCore.gridOptions.orderSize)}); 
      }, 
      } 
    ]; 
    return menuItems; 
} 

你能幫助我嗎?

編輯

我注意到,在創建ViewportDatasource對象時,事件監聽功能不會被調用。我如何強制它?

EDIT 2

我把ViewportDatasource聲明出來WatcherTable範圍。現在我解決了開始的問題,但我無法將數據加載到網格中。 (今日從你的問題採取這裏類似的問題,我認爲)https://plnkr.co/edit/EEEJULRE72nbPF6G0PCK

+0

你可以創建一個plunker嗎? – Aravind

+0

我不認爲我可以添加ag-grid的企業版 –

+0

您是否包含[示例]中的mockServer.js文件(https://www.ag-grid.com/javascript-grid-viewport/) exampleViewport.html)你提到過嗎? –

回答

1

您的plunker一個時間問題 - 你MockServer試圖處理的數據是可用之前:

我創建了一個plunker 。

你需要做兩件事情來解決這個 - 第一個是隻嘗試一次在MockServer數據可設置數​​據源:

WatcherTable.prototype.setRowData = function ($http) { 
    // set up a mock server - real code will not do this, it will contact your 
    // real server to get what it needs 
    var mockServer = new MockServer(); 
    var that = this; 
    $http.get('data.json').then(function (response) { 
     mockServer.init(response.data); 
     var viewportDatasource = new ViewportDatasource(mockServer); 
     that.table.api.setViewportDatasource(viewportDatasource); 
     // put the 'size cols to fit' into a timeout, so that the scroll is taken into consideration 
     setTimeout(function() { 
      that.table.api.sizeColumnsToFit(); 
     }, 100); 
    }); 
} 

其次,沿着同一個主題,你需要防止定期更新在準備好之前嘗試處理數據。在這裏,你可以揭開序幕,定期更新後的數據是可用的,或者更簡單地增加一個檢查您嘗試使用它之前:

MockServer.prototype.periodicallyUpdateData = function() { 
    if(!this.allData) return; 

我已經分叉的plunker(上述變更)位置:https://plnkr.co/edit/cY30aHIPydVOjcihX8Zh?p=preview

相關問題