WedX - журнал о программировании и компьютерных науках

Область просмотра сетки Ag: невозможно прочитать свойство "привязка" неопределенного значения

Я копирую пример окна просмотра ag-grid, помещая его в объект, представляющий таблицу, вместо анонимной функции. Я не могу понять, почему он дает мне ошибку в заголовке при попытке подключиться к mockserver, учитывая, что это точно такой же код.

Вот код, который, похоже, не работает:

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

Можешь мне помочь?

ИЗМЕНИТЬ

Я заметил, что функция eventListener не вызывается при создании объекта ViewportDatasource. Как я могу это заставить?

ИЗМЕНИТЬ 2

Я взял объявление ViewportDatasource из области WatcherTable. Теперь я решил стартовую проблему, но не могу загрузить данные в сетку.

Я создал плункер: https://plnkr.co/edit/EEEJULRE72nbPF6G0PCK

23.01.2017

  • вы можете создать плункер? 23.01.2017
  • Я не думаю, что смогу добавить корпоративную версию ag-grid 23.01.2017
  • Включили ли вы файл mockServer.js, который находится в примере Вы упомянули? 23.01.2017
  • Да, взял как есть. Если я использую exampleViewport.js со своими стилями и рендерерами, он работает нормально, но мне нужно определить объект, и в этом случае он не работает. 23.01.2017

Ответы:


1

(Взято из вашего сегодняшнего вопроса, я думаю, что здесь похожие проблемы)

У вас проблема с синхронизацией в вашем плункере - ваш MockServer пытается обработать данные до того, как они станут доступны.

Чтобы решить эту проблему, вам нужно сделать две вещи: первая - попытаться установить источник данных только после того, как данные станут доступны в 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;

Я раздвоил ваш плункер (с указанными выше изменениями) здесь: https://plnkr.co/edit/cY30aHIPydVOjcihX8Zh?p=preview

25.01.2017
Новые материалы

Как создать диаграмму градиентной кисти с помощью D3.js
Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

Объяснение документов 02: BERT
BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

Как проанализировать работу вашего классификатора?
Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

Работа с цепями Маркова, часть 4 (Машинное обучение)
Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


Для любых предложений по сайту: [email protected]