TonyGermaneri / canvas-datagrid

Canvas based data grid web component. Capable of displaying millions of contiguous hierarchical rows and columns without paging or loading, on a single canvas element.
BSD 3-Clause "New" or "Revised" License
1.45k stars 188 forks source link

Can't use with Angular 11? #335

Open Smokovsky opened 3 years ago

Smokovsky commented 3 years ago

I'm trying to use canvas-datagrid with Angular 11 but I can't. I've created a new project, then installed canvas-datagrid, and tried a few approaches to get it to work.

I added canvas-datagrid.js into scripts in angular.json. I have also imported it to my component.ts like this import * as canvasDatagrid from 'canvas-datagrid';

Tried to follow the example and added some HTML:

<canvas-datagrid class="myGridStyle" data="">[
    {"col1": "row 1 column 1", "col2": "row 1 column 2", "col3": "row 1 column 3"},
    {"col1": "row 2 column 1", "col2": "row 2 column 2", "col3": "row 2 column 3"}
]</canvas-datagrid>

Unfortunatelly got error NG8001: 'canvas-datagrid' is not a known element. I tried to import somehow this component to app.module but couldn't.

Then tried the second way of implementation:

grid = canvasDatagrid();

ngOnInit(){
    document.body.appendChild(this.grid);
    this.grid.data = [
        {col1: 'row 1 column 1', col2: 'row 1 column 2', col3: 'row 1 column 3'},
        {col1: 'row 2 column 1', col2: 'row 2 column 2', col3: 'row 2 column 3'}
    ];
} 

Error: Uncaught DOMException: Failed to execute 'define' on 'CustomElementRegistry': the name "canvas-datagrid" has already been used with this registry at CustomElementRegistry.target. [as define]

Third approach

grid = canvasDatagrid({
    parentNode: document.getElementById('gridctr'),
    data: [{col1: 'foo', col2: 0, col3: 'a'},
    {col1: 'bar', col2: 1, col3: 'b'},
    {col1: 'baz', col2: 2, col3: 'c'}]
});

Got the same error as in second.

Finally I tried to put <canvas-datagrid>[]</canvas-datagrid> in HTML and while app was served, it was showing like one cell of spreadsheet, getting console error on click: "Cannot read property 'length' of undefined". If added first, then serving the app, getting "Cannot GET/" result.

What am I doing wrong? How to use it on Angular?

TonyGermaneri commented 3 years ago

I haven't used Angular before so I can't say exactly what is going wrong here. The error Failed to execute 'define' would occur if it was getting registered twice. Is there another place you're registering something with the same name as a web component maybe by accident? I don't think this lib would try and register itself twice. At least I haven't heard that bug before.

For the first error it saying 'canvas-datagrid' is not a known element likely means the lib was not given enough time to load before the page was rendered. That sounds like the easier path to take to implement. You just need to make sure the canvas-datagrid lib is finished loading (it's all sync) before you try and render your page. I haven't used angular so I don't know the framework specific way you're supposed to do that - and surely there is a good/bad way to do it in angular. You should google "angular custom element" and see how they want you to import such things.

A bad way to do it without knowing much about angular is to load the canvas-datagrid lib before the angular lib. That would ensure the custom element is registered. Unless it is angular complaining about the thing, in which case there is likely an angular setting to suppress this error, there is such a thing in Vue.

Smokovsky commented 3 years ago

Oh that's bad. I'd really love to use your library in my project. I push this case a little bit forward but stuck again, maybe you will know what is up. So, I've addedschemas: [ CUSTOM_ELEMENTS_SCHEMA ] to my app.module, which is supposed to eliminate error that says it is not known element. It worked, I served the app, compiled, no errors. But...

I tried old good <canvas-datagrid>[]</canvas-datagrid>, (visual effect the same as before):

Screenshot: https://imgur.com/wKSSBJG

Clicking on it still produces error: core.js:5980 ERROR TypeError: Cannot read property 'length' of undefined. I was trying to pass something between those selectors but it failed. Anyways I passed something with data property.

<canvas-datagrid data="[{col1: 'foo', col2: 0, col3: 'a'},
                          {col1: 'bar', col2: 1, col3: 'b'}]">
  </canvas-datagrid>

Displayed element on page changed, it's showing a column now, but it produces errors when served.

Screenshot: https://imgur.com/o0SNRc6

Clicking on this old element still produces Cannot read property 'length', anyways clicking on this A column seems to work fine, it makes the arrow showing sort direction change to the opposite.

Any further ideas?

ps. @re:1st-paragraph: There is no way that I could define canvas-datagrid myself, also it's a brand new project, I tried to add this library with script tag in index.html head - makes no difference with adding it under scripts in angular.json. Then I described all I did with the component supposed to display grid.

Dassderdie commented 3 years ago

Here is an example project how to use this library with angular: https://ng-run.com/edit/V8aQLT3Ubbg3v5b1zhig

The important stuff:

app.component.ts

import { Component, VERSION, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
// @ts-expect-error canvas datagrid doesn't have typings yet
import * as canvasDatagrid from 'canvas-datagrid';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
  @ViewChild('container') container: ElementRef<HTMLDivElement>;

  ngAfterViewInit() {
    const grid = canvasDatagrid({
      parentNode: this.container.nativeElement,
      data: [{ col1: 'foo', col2: 0, col3: 'a' },
      { col1: 'bar', col2: 1, col3: 'b' },
      { col1: 'baz', col2: 2, col3: 'c' }]
    });
  }
} 

app.component.html

<div #container style="width: 100%"></div>

And you have to add canvas-datagrid to the dependencies in package.json and run npm i.

reza3vi commented 3 years ago

html

<canvas-datagrid #datatable [style.width.%]="100" [style.height.px]="600" [style.direction]="'ltr'" [data]="data" (rendercell)="rendercell($event)"> </canvas-datagrid>

ts @ViewChild('datatable') datatable: any; this.datatable.nativeElement.scrollIntoView(1, 3);

Dassderdie commented 3 years ago

I think this issue can be closed?

kirubha27 commented 2 years ago

@Dassderdie am trying to use canvas-datagrid(version-0.3.2) in angular 12,if i installed latest version of 0.4.5,application is not compiling only,so used 0.3.2 and issue is Screenshot 2022-09-28 at 4 59 19 PM