From e6d4fcc1761ed79d550e720d493bd313b33ebadf Mon Sep 17 00:00:00 2001 From: riccardoperra Date: Thu, 27 Jun 2024 20:16:32 +0200 Subject: [PATCH 1/3] fix: update view when content type change --- .../src/__tests__/flex-render.test.ts | 29 ++++++++------ packages/angular-table/src/flex-render.ts | 38 ++++++++++--------- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/packages/angular-table/src/__tests__/flex-render.test.ts b/packages/angular-table/src/__tests__/flex-render.test.ts index 6d678c573c..4c1fa04bc3 100644 --- a/packages/angular-table/src/__tests__/flex-render.test.ts +++ b/packages/angular-table/src/__tests__/flex-render.test.ts @@ -1,7 +1,6 @@ import { Component, ViewChild, input, type TemplateRef } from '@angular/core' import { TestBed, type ComponentFixture } from '@angular/core/testing' import { createColumnHelper } from '@tanstack/table-core' -import { skip } from 'node:test' import { describe, expect, test } from 'vitest' import { FlexRenderComponent, @@ -24,6 +23,20 @@ describe('FlexRenderDirective', () => { test('should render primitives', async () => { const fixture = TestBed.createComponent(TestRenderComponent) + // Null + setFixtureSignalInputs(fixture, { + content: () => null, + context: {}, + }) + expect((fixture.nativeElement as HTMLElement).matches(':empty')).toBe(true) + + // Undefined + setFixtureSignalInputs(fixture, { + content: () => undefined, + context: {}, + }) + expect((fixture.nativeElement as HTMLElement).matches(':empty')).toBe(true) + // String setFixtureSignalInputs(fixture, { content: 'My value', @@ -45,19 +58,12 @@ describe('FlexRenderDirective', () => { }) expectPrimitiveValueIs(fixture, 'My value 2') - // Null + // Set again to null to be sure content is destroyed has been destroyed setFixtureSignalInputs(fixture, { content: () => null, context: {}, }) - expectPrimitiveValueIs(fixture, '') - - // Undefined - setFixtureSignalInputs(fixture, { - content: () => undefined, - context: {}, - }) - expectPrimitiveValueIs(fixture, '') + expect((fixture.nativeElement as HTMLElement).matches(':empty')).toBe(true) }) test('should render TemplateRef', () => { @@ -118,7 +124,7 @@ describe('FlexRenderDirective', () => { // Skip for now, test framework (using ComponentRef.setInput) cannot recognize signal inputs // as component inputs - skip('should render custom components', () => { + test.skip('should render custom components', () => { @Component({ template: `{{ row().property }}`, standalone: true, @@ -172,6 +178,7 @@ function expectPrimitiveValueIs( fixture: ComponentFixture, value: unknown ) { + expect(fixture.nativeElement.matches(':empty')).toBe(false) const span = fixture.nativeElement.querySelector('span') expect(span).toBeDefined() expect(span.innerHTML).toEqual(value) diff --git a/packages/angular-table/src/flex-render.ts b/packages/angular-table/src/flex-render.ts index be1d114dd1..f69ce6570d 100644 --- a/packages/angular-table/src/flex-render.ts +++ b/packages/angular-table/src/flex-render.ts @@ -2,18 +2,19 @@ import { ChangeDetectorRef, ComponentRef, Directive, + type DoCheck, EmbeddedViewRef, Inject, + inject, InjectionToken, Injector, Input, + isSignal, + type OnChanges, + type SimpleChanges, TemplateRef, Type, ViewContainerRef, - inject, - isSignal, - type DoCheck, - type OnInit, } from '@angular/core' export type FlexRenderContent> = @@ -30,13 +31,14 @@ export type FlexRenderContent> = standalone: true, }) export class FlexRenderDirective> - implements OnInit, DoCheck + implements OnChanges, DoCheck { @Input({ required: true, alias: 'flexRender' }) content: | number | string | ((props: TProps) => FlexRenderContent) + | null | undefined = undefined @Input({ required: true, alias: 'flexRenderProps' }) @@ -54,14 +56,18 @@ export class FlexRenderDirective> ref?: ComponentRef | EmbeddedViewRef | null = null - ngOnInit(): void { - this.ref = this.render() + ngOnChanges(changes: SimpleChanges) { + if (this.ref instanceof ComponentRef) { + this.ref.injector.get(ChangeDetectorRef).markForCheck() + } + if (!changes['content']) { + return + } + this.render() } ngDoCheck() { - if (this.ref instanceof ComponentRef) { - this.ref.injector.get(ChangeDetectorRef).markForCheck() - } else if (this.ref instanceof EmbeddedViewRef) { + if (this.ref instanceof EmbeddedViewRef) { this.ref.markForCheck() } } @@ -69,17 +75,15 @@ export class FlexRenderDirective> render() { this.viewContainerRef.clear() const { content, props } = this - if (!this.content) { - return null - } - - if (typeof content === 'string' || typeof content === 'number') { - return this.renderStringContent() + if (content === null || content === undefined) { + this.ref = null + return } if (typeof content === 'function') { return this.renderContent(content(props)) + } else { + return this.renderContent(content) } - return null } private renderContent(content: FlexRenderContent) { From 3cfb4f5fbad973fb27dda82daa6b07beeb84d2a9 Mon Sep 17 00:00:00 2001 From: riccardoperra Date: Thu, 27 Jun 2024 20:29:38 +0200 Subject: [PATCH 2/3] fix: update view when content type change --- packages/angular-table/src/flex-render.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/angular-table/src/flex-render.ts b/packages/angular-table/src/flex-render.ts index f69ce6570d..86f97ae6cb 100644 --- a/packages/angular-table/src/flex-render.ts +++ b/packages/angular-table/src/flex-render.ts @@ -2,7 +2,6 @@ import { ChangeDetectorRef, ComponentRef, Directive, - type DoCheck, EmbeddedViewRef, Inject, inject, @@ -31,7 +30,7 @@ export type FlexRenderContent> = standalone: true, }) export class FlexRenderDirective> - implements OnChanges, DoCheck + implements OnChanges { @Input({ required: true, alias: 'flexRender' }) content: @@ -66,12 +65,6 @@ export class FlexRenderDirective> this.render() } - ngDoCheck() { - if (this.ref instanceof EmbeddedViewRef) { - this.ref.markForCheck() - } - } - render() { this.viewContainerRef.clear() const { content, props } = this From a60caf7e11937a06b36fbaa3fff81471255c4b62 Mon Sep 17 00:00:00 2001 From: riccardoperra Date: Thu, 27 Jun 2024 20:36:02 +0200 Subject: [PATCH 3/3] fix: update view when content type change --- packages/angular-table/src/__tests__/flex-render.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/angular-table/src/__tests__/flex-render.test.ts b/packages/angular-table/src/__tests__/flex-render.test.ts index 4c1fa04bc3..217574de54 100644 --- a/packages/angular-table/src/__tests__/flex-render.test.ts +++ b/packages/angular-table/src/__tests__/flex-render.test.ts @@ -58,7 +58,7 @@ describe('FlexRenderDirective', () => { }) expectPrimitiveValueIs(fixture, 'My value 2') - // Set again to null to be sure content is destroyed has been destroyed + // Set again to null to be sure content has been destroyed setFixtureSignalInputs(fixture, { content: () => null, context: {},