ghiscoding / Angular-Slickgrid

Angular-Slickgrid is a wrapper of the lightning fast & customizable SlickGrid datagrid, it also includes multiple Styling Themes
https://ghiscoding.github.io/Angular-Slickgrid
MIT License
396 stars 119 forks source link

Row Detail - No component factory found for undefined. #387

Closed HFTSOL closed 4 years ago

HFTSOL commented 4 years ago

General Topic

Your Environment

Software Version(s)
Angular 8.2.7
Angular-Slickgrid 2.16.5
TypeScript 3.5.3
Operating System W10 Pro
NPM/Node/Yarn 6.10.3/12.10.0

Context or Topic

Expected Behavior

Current Behavior

Possible Solution

Good day,

I have a grid that I'm trying to add a Row Detail to. I created the component, added it to the Entry Components, and referenced the component in the rowDetailView configuration. When I click expand the row, I'm getting the error below. The row does expand, but it doesn't render the component.

No component factory found for undefined. Did you add it to @NgModule.entryComponents?

Again, the component has been added to both the module declarations, and entryComponents. I didn't see anything in your Wiki or examples of explicit registration of the component with your module anywhere. Is there a step missing somewhere?

Grid Component HTML

<div [id]="containerId" class="example-grid" [style.height.px]="contentHeight" *ngIf="containerId"> <angular-slickgrid [columnDefinitions]="columnDefinitions" [dataset]="players" [gridHeight]="contentHeight" [gridId]="gridId" [gridOptions]="gridOptions" (onAngularGridCreated)="angularGridReady($event)">

Grid Options in Grid Component

this.gridOptions = {
  datasetIdPropertyName: 'playerId',
  enableAutoResize: false,
  enableRowDetailView: true,
  gridContainerId: this.containerId,
  gridId: this.gridId,
  rowDetailView: {
    loadOnce: true,
    panelRows: 5,
    process: this._getPlayer.bind(this),
    singleRowExpand: true,
    useRowClick: true,
    viewComponent: ExampleRowDetailComponent
  },
  rowSelectionOptions: {
    selectActiveRow: true
  },
};

ExampleRowDetailComponent ` @Component({ encapsulation: ViewEncapsulation.None, selector: 'example-row-detail', template: '...template would go here...', styles: [''] }) export class ExampleRowDetailComponent implements OnInit {

public addon: any; // row detail addon instance public dataView: any; public grid: any; public model: IMagnetPlayerInfo;

constructor(private _logger: LoggingService) { // this._logger.debug(${this.CLASSNAME} > constructor()); }

public ngOnInit(): void { } } `

Full Error ERROR Error: No component factory found for undefined. Did you add it to @NgModule.entryComponents? at noComponentFactoryError (core.js:25606) at CodegenComponentFactoryResolver.resolveComponentFactory (core.js:25682) at AngularUtilService.createAngularComponent (angular-slickgrid.js:261) at AngularUtilService.createAngularComponentAppendToDom (angular-slickgrid.js:275) at RowDetailViewExtension.renderPreloadView (angular-slickgrid.js:8219) at RowDetailView.<anonymous> (angular-slickgrid.js:8157) at Event.notify (slick.core.js:183) at SlickGrid.handleClick (slick.rowdetailview.js:254) at Event.notify (slick.core.js:183) at trigger (slick.grid.js:2555)

ghiscoding commented 4 years ago

I would suggest you to clone the Angular-Slickgrid-Demos and play with the Row Detail in there, Your issue seems to be an Angular issue with how you import the component you use for the Row Detail, which is most probably not related to the lib itself, you can google that and I'm sure you'll find an answer or clone the demo like I said. The demo works and that is all what I'm interested in.

If you can't find an answer, I would prefer that you ask such kind of questions on Stack Overflow, you'll get more answers from the community instead of just 1 person (me). I prefer to keep only issues in here... However if you find that the Wiki could be improved and you have the text, then feel free to let me know. Thanks

HFTSOL commented 4 years ago

I actually have several dynamically rendered components in my application and they all work fine. I believe the issue is that your module is trying to render a component that it has no direct knowledge of since it's not being imported by your module before use.

To be honest, I would prefer a way to use an Angular template instead of a component. Since your expressed purpose for the functionality is to show more detail about the row, using a separate component seems a bit excessive for the majority of scenarios. I would like it if it worked, but that's not really necessary for my situation.

Also, since all the data I need for the rowDetail is already in the item, having to pass it to a function that returns it as an observable is definitely excessive and I would like to see a way to bypass the need for a process and just use the item as is.

HFTSOL commented 4 years ago

I guess what I should have started with was: Thanks for building this library. It looks great, and I'm really hoping it will work for our grid needs.

ghiscoding commented 4 years ago

The way I found is to compile the Angular component into a usable html template for SlickGrid Row Detail plugin (because remember that SlickGrid is a plain jQuery lib and Angular-Slickgrid is a wrapper on top of it). This is mainly all done by this Angular Util Service in the lib and as pointed out in the service, I found this article, I would assume that it probably has to be a Component that has all necessary stuff at hand (not in the future) for it to work. I know there are plenty of people using the Row Detail, since I've seen a few SO questions and GitHub issues, but personally I haven't used it on any projects yet

If you have better ways of dealing with dynamic Angular Components then feel free to submit a PR, we can add new properties to the row detail grid options if your implementation differs from the way I already have.

HFTSOL commented 4 years ago

Actually, I started focusing on the second error I was getting about the item not having an 'id' property even though I specified that the id column for the grid was the 'playerId' field. I artificially added the 'id' field and it started rendering the component.

That being said, I'm still seeing the error, so it's definitely something inside your library that my odd circumstances are causing. I'll let you know if I chase it down. In the meantime I'll add a feature request to have the datasetIdPropertyName also apply to the rowDetailView.

ghiscoding commented 4 years ago

Adding the into the Row Detail plugin was already done in SlickGrid 3rd party plugin in this PR, though it seems I might have forgot to apply it in my lib with the Row Detail Extension, searching for the text ".id" seems to be used in a few places, I could fix that eventually by using the datasetIdPropertyName or id (for now provide an id as you found out) but for the other templating issue, that would be on your side.

HFTSOL commented 4 years ago

As a rule, the client should never modify entities coming from the server, so adding an id field to the entities is a horrible practice that I would not be using for a production application. The tool should definitely be able to adapt to the data definition.

I don't want you to think I'm downing your lib though. I really like your modernization of SlickGrid and will be looking for ways to contribute to it's progress going forward.

ghiscoding commented 4 years ago

I did pass couple of thousand hours of time to get to what it is now, so yes I do appreciate when people stay respectful, especially since this is a Free and Open Source library, which I'm not paid for and I just ask people to upvote.

ghiscoding commented 4 years ago

The missing datasetIdPropertyName in the Row Detail extension is now fixed and was pushed under the new version 2.17.x. The Row Detail Example was also updated to make sure that it all works.

If you find a better way of creating dynamic component, feel free to bring in a PR.