Skip to content

Commit bfa96d8

Browse files
authoredJun 29, 2024··
fix(angular-table): View is not updated anymore when flexRenderDirective is instantiated the first time with an empty value (#5626)
* fix: update view when content type change
1 parent 78b9012 commit bfa96d8

File tree

2 files changed

+34
-30
lines changed

2 files changed

+34
-30
lines changed
 

‎packages/angular-table/src/flex-render.ts

+16-19
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ import {
44
Directive,
55
EmbeddedViewRef,
66
Inject,
7+
inject,
78
InjectionToken,
89
Injector,
910
Input,
11+
isSignal,
12+
type OnChanges,
13+
type SimpleChanges,
1014
TemplateRef,
1115
Type,
1216
ViewContainerRef,
13-
inject,
14-
isSignal,
15-
type DoCheck,
16-
type OnInit,
1717
} from '@angular/core'
1818

1919
export type FlexRenderContent<TProps extends NonNullable<unknown>> =
@@ -30,13 +30,14 @@ export type FlexRenderContent<TProps extends NonNullable<unknown>> =
3030
standalone: true,
3131
})
3232
export class FlexRenderDirective<TProps extends NonNullable<unknown>>
33-
implements OnInit, DoCheck
33+
implements OnChanges
3434
{
3535
@Input({ required: true, alias: 'flexRender' })
3636
content:
3737
| number
3838
| string
3939
| ((props: TProps) => FlexRenderContent<TProps>)
40+
| null
4041
| undefined = undefined
4142

4243
@Input({ required: true, alias: 'flexRenderProps' })
@@ -54,32 +55,28 @@ export class FlexRenderDirective<TProps extends NonNullable<unknown>>
5455

5556
ref?: ComponentRef<unknown> | EmbeddedViewRef<unknown> | null = null
5657

57-
ngOnInit(): void {
58-
this.ref = this.render()
59-
}
60-
61-
ngDoCheck() {
58+
ngOnChanges(changes: SimpleChanges) {
6259
if (this.ref instanceof ComponentRef) {
6360
this.ref.injector.get(ChangeDetectorRef).markForCheck()
64-
} else if (this.ref instanceof EmbeddedViewRef) {
65-
this.ref.markForCheck()
6661
}
62+
if (!changes['content']) {
63+
return
64+
}
65+
this.render()
6766
}
6867

6968
render() {
7069
this.viewContainerRef.clear()
7170
const { content, props } = this
72-
if (!this.content) {
73-
return null
74-
}
75-
76-
if (typeof content === 'string' || typeof content === 'number') {
77-
return this.renderStringContent()
71+
if (content === null || content === undefined) {
72+
this.ref = null
73+
return
7874
}
7975
if (typeof content === 'function') {
8076
return this.renderContent(content(props))
77+
} else {
78+
return this.renderContent(content)
8179
}
82-
return null
8380
}
8481

8582
private renderContent(content: FlexRenderContent<TProps>) {

‎packages/angular-table/tests/flex-render.test.ts

+18-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Component, ViewChild, input, type TemplateRef } from '@angular/core'
22
import { TestBed, type ComponentFixture } from '@angular/core/testing'
33
import { createColumnHelper } from '@tanstack/table-core'
4-
import { skip } from 'node:test'
54
import { describe, expect, test } from 'vitest'
65
import {
76
FlexRenderComponent,
@@ -24,6 +23,20 @@ describe('FlexRenderDirective', () => {
2423
test('should render primitives', async () => {
2524
const fixture = TestBed.createComponent(TestRenderComponent)
2625

26+
// Null
27+
setFixtureSignalInputs(fixture, {
28+
content: () => null,
29+
context: {},
30+
})
31+
expect((fixture.nativeElement as HTMLElement).matches(':empty')).toBe(true)
32+
33+
// Undefined
34+
setFixtureSignalInputs(fixture, {
35+
content: () => undefined,
36+
context: {},
37+
})
38+
expect((fixture.nativeElement as HTMLElement).matches(':empty')).toBe(true)
39+
2740
// String
2841
setFixtureSignalInputs(fixture, {
2942
content: 'My value',
@@ -45,19 +58,12 @@ describe('FlexRenderDirective', () => {
4558
})
4659
expectPrimitiveValueIs(fixture, 'My value 2')
4760

48-
// Null
61+
// Set again to null to be sure content has been destroyed
4962
setFixtureSignalInputs(fixture, {
5063
content: () => null,
5164
context: {},
5265
})
53-
expectPrimitiveValueIs(fixture, '')
54-
55-
// Undefined
56-
setFixtureSignalInputs(fixture, {
57-
content: () => undefined,
58-
context: {},
59-
})
60-
expectPrimitiveValueIs(fixture, '')
66+
expect((fixture.nativeElement as HTMLElement).matches(':empty')).toBe(true)
6167
})
6268

6369
test('should render TemplateRef', () => {
@@ -118,7 +124,7 @@ describe('FlexRenderDirective', () => {
118124

119125
// Skip for now, test framework (using ComponentRef.setInput) cannot recognize signal inputs
120126
// as component inputs
121-
skip('should render custom components', () => {
127+
test.skip('should render custom components', () => {
122128
@Component({
123129
template: `{{ row().property }}`,
124130
standalone: true,
@@ -172,6 +178,7 @@ function expectPrimitiveValueIs(
172178
fixture: ComponentFixture<unknown>,
173179
value: unknown
174180
) {
181+
expect(fixture.nativeElement.matches(':empty')).toBe(false)
175182
const span = fixture.nativeElement.querySelector('span')
176183
expect(span).toBeDefined()
177184
expect(span.innerHTML).toEqual(value)

0 commit comments

Comments
 (0)
Please sign in to comment.