Skip to content

Conversation

MayaKirova
Copy link
Contributor

Closes #15768
Closes #15911
Closes IgniteUI/igniteui-webcomponents#1861

Additional information (check all that apply):

  • Bug fix
  • New functionality
  • Documentation
  • Demos
  • CI/CD

Checklist:

  • All relevant tags have been applied to this PR
  • This PR includes unit tests covering all the new code (test guidelines)
  • This PR includes API docs for newly added methods/properties (api docs guidelines)
  • This PR includes feature/README.MD updates for the feature docs
  • This PR includes general feature table updates in the root README.MD
  • This PR includes CHANGELOG.MD updates for newly added functionality
  • This PR contains breaking changes
  • This PR includes ng update migrations for the breaking changes (migrations guidelines)
  • This PR includes behavioral changes and the feature specification has been updated with them

* ```
*/
public show(context?: any): void {
if(!this._originalParent) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, if every workflow goes through show we might even move the caching of the original parent here ngAfterViewInit where it was originally, so both cache and return are on the show/hide pair.

Anyway, I'm assuming this fixes the disappearing strip if it inits in some case as detached, but still is attached before showing.

const grid = context.grid;
grid.deleteRow(context.key);

this.grid.cdr.detectChanges();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, the original parent bit I get, but do we really need this? Any context why a full grid change detection is needed/doing?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surely the deletion and CRUD service will also do that if needed, so this one would be extra even.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deleteRow removes the record from the data, but the actual removal of the DOM element happens on the next change detection. This creates a bit of a timing issue.

I no longer remember the details, since it has been a while, however I can confirm that the code does not work without the change detection (the issue reproduces without the change detection and is fixed with the change detection).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@damyanpetev Here are a few observation.

The issue is specifically when you delete the last row and there's no next row in the grid, for example you have a grid with only 2 rows and you delete the second one. So this means that the RowComponent associated with the row will be destroyed. The issue happens when the moment the row is destroyed the action strip is still inside it:

image

Hence the destroy and removal of the row, also removes and destroys the action strip.

To me it seems that the logic that moves the action strip back to the root of the grid, the one inside the hide API:

  this.renderer.appendChild(this._originalParent, this._viewContainer.element.nativeElement);

Happens asynchronously - so it does not immediately move it to the root in time, before angular goes and destroys the parent. So regardless of the order:

        this.strip.hide();
        grid.deleteRow(context.key);

or

 grid.deleteRow(context.key);
 this.strip.hide();

It never manages to move the strip out of the row in time.

Also another fun observation - if you debug the deleteRowHandler code or the one inside the hide method, the issue stops reproducing as then the code executes synchronously and moves the strip to the root just fine.

Adding a change detection somewhere in the deleteRowHandler (doesn't matter where - before, between or after the other actions) seems to force it to resolve the operation and causes it work again.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MayaKirova you're right to suspect something async happening, sure, except it's not the appendChild being async (that one is very much synchronous for the dom version). The The actual delete calls markForCheck and the actual re-render happens on next cycle so order of calls in that location doesn't change the outcome.

What I'm actually observing is quite interesting:

this.strip.hide();

works exactly as it should and moves the strip back to the grid element (can confirm with a simple log to avoid messing with timing during debug). Except something else moves the strip back to the row and gets it deleted permanently from the DOM by destroying the row. That's why the detectChanges() helps, cuz it forces the deletion to happen first, so the return to DOM on hide() sticks.

Logpoint at the end of hide like so
image
and one on renderer.removeChild yields the following when I hit the delete on a single row:
image

So the actual issue which I haven't dug out yet - why on earth is the action strip returning to its row just before it gets destroyed so it can deleted along with its DOM host.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@damyanpetev It seems to me that the show gets called after the hide, so it moves it back:
image
Probably because the row is not yet deleted and the mouse is still over it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image Yeah, was just going to note that there's a secondary show()

@MayaKirova MayaKirova requested a review from damyanpetev October 9, 2025 13:01
Copy link
Member

@damyanpetev damyanpetev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, this is way more logical than a forced change detection :)
Would still love to prevent the extra show in this scenario, though that'd be much more involved of a fix for another time, and the destroy cleanup still makes sense regardless.

PS: Also wouldn't mind an Angular/Elements test at some point covering this.

@damyanpetev damyanpetev added the squash-merge Merge PR with "Squash and Merge" option label Oct 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action-strip 💠 grid: elements grid squash-merge Merge PR with "Squash and Merge" option version: 20.1.x ❌ status: awaiting-test PRs awaiting manual verification

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants