Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e004157

Browse files
committed
feat(demos): add reconciling comparison demo
1 parent 78ed9aa commit e004157

File tree

6 files changed

+256
-88
lines changed

6 files changed

+256
-88
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Component, OnDestroy } from '@angular/core';
2+
3+
@Component({
4+
selector: 'list-action-item',
5+
template: ` <ng-content /> `,
6+
styles: [
7+
`
8+
:host {
9+
display: contents;
10+
}
11+
`,
12+
],
13+
})
14+
export class ListActionItemComponent implements OnDestroy {
15+
ngOnDestroy() {
16+
// console.log('onDestroy');
17+
}
18+
}

apps/demos/src/app/features/template/rx-for/list-actions/list-actions.component.ts

Lines changed: 193 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,43 @@
11
import {
22
AfterViewInit,
3+
ChangeDetectionStrategy,
34
ChangeDetectorRef,
45
Component,
56
ElementRef,
67
NgZone,
78
QueryList,
9+
signal,
810
ViewChild,
911
ViewChildren,
1012
ViewEncapsulation,
1113
} from '@angular/core';
12-
import { asyncScheduler } from 'rxjs-zone-less';
14+
import { coalesceWith } from '@rx-angular/cdk/coalescing';
15+
import { RxState } from '@rx-angular/state';
1316
import {
17+
animationFrameScheduler,
1418
BehaviorSubject,
19+
combineLatest,
1520
defer,
1621
merge,
17-
Observable,
1822
scheduled,
1923
Subject,
2024
} from 'rxjs';
21-
import { environment } from '../../../../../environments/environment';
25+
import { asyncScheduler } from 'rxjs-zone-less';
26+
import {
27+
delay,
28+
map,
29+
shareReplay,
30+
switchMap,
31+
switchMapTo,
32+
} from 'rxjs/operators';
33+
import { Hooks } from '../../../../shared/debug-helper/hooks';
2234
import {
2335
ArrayProviderService,
2436
removeItemsImmutable,
2537
shuffleItemsImmutable,
2638
TestItem,
2739
} from '../../../../shared/debug-helper/value-provider';
2840
import { ArrayProviderComponent } from '../../../../shared/debug-helper/value-provider/array-provider/array-provider.component';
29-
import { RxState } from '@rx-angular/state';
30-
import { Hooks } from '../../../../shared/debug-helper/hooks';
31-
import { map, switchMap, switchMapTo } from 'rxjs/operators';
3241

3342
let itemIdx = 0;
3443

@@ -149,96 +158,175 @@ const moveChangeSet1 = [items5k];
149158
selector: 'rxa-rx-for-list-actions',
150159
template: `
151160
<rxa-visualizer>
152-
<div visualizerHeader class="row">
153-
<div class="col-sm-12">
154-
<h2>Reactive Iterable Differ</h2>
155-
<rxa-array-provider
156-
[unpatched]=""
157-
[buttons]="true"
158-
#arrayP="rxaArrayProvider"
159-
></rxa-array-provider>
160-
<rxa-strategy-select
161-
(strategyChange)="strategy$.next($event)"
162-
></rxa-strategy-select>
163-
<mat-button-toggle-group
164-
name="visibleExamples"
165-
*rxLet="view; let viewMode"
166-
aria-label="Visible Examples"
167-
[value]="viewMode"
168-
#group="matButtonToggleGroup"
169-
>
170-
<mat-button-toggle value="tile" (click)="view.next('tile')"
171-
>Tile
172-
</mat-button-toggle>
173-
<mat-button-toggle value="list" (click)="view.next('list')"
174-
>List
175-
</mat-button-toggle>
176-
</mat-button-toggle-group>
177-
<button mat-raised-button (click)="triggerChangeSet.next()">
178-
ChangeSet
179-
</button>
180-
<button mat-raised-button (click)="triggerMoveSet.next()">
181-
MoveSet
182-
</button>
183-
<button mat-raised-button (click)="triggerMoveSetSwapped.next()">
184-
MoveSet Swapped
185-
</button>
186-
<p *rxLet="rendered$; let rendered">
187-
<strong>Rendered</strong> {{ rendered }}
188-
</p>
189-
<p *rxLet="viewBroken$; let viewBroken">
190-
<ng-container>
191-
<span [ngStyle]="{ color: viewBroken ? 'red' : 'green' }"
192-
>VIEW BROKEN {{ viewBroken }}</span
193-
>
194-
</ng-container>
195-
</p>
161+
<ng-container visualizerHeader>
162+
<div class="row">
163+
<div class="col-sm-12">
164+
<h2>Reactive Iterable Differ</h2>
165+
<rxa-array-provider
166+
[unpatched]=""
167+
[buttons]="true"
168+
#arrayP="rxaArrayProvider"
169+
></rxa-array-provider>
170+
<rxa-strategy-select
171+
(strategyChange)="strategy$.next($event)"
172+
></rxa-strategy-select>
173+
<mat-button-toggle-group
174+
name="visibleExamples"
175+
*rxLet="view; let viewMode"
176+
aria-label="Visible Examples"
177+
[value]="viewMode"
178+
#group="matButtonToggleGroup"
179+
>
180+
<mat-button-toggle value="tile" (click)="view.next('tile')"
181+
>Tile
182+
</mat-button-toggle>
183+
<mat-button-toggle value="list" (click)="view.next('list')"
184+
>List
185+
</mat-button-toggle>
186+
</mat-button-toggle-group>
187+
<mat-button-toggle-group
188+
[value]="reconciler()"
189+
#group="matButtonToggleGroup"
190+
>
191+
<mat-button-toggle
192+
value="experimental"
193+
(click)="reconciler.set('experimental')"
194+
>experimental
195+
</mat-button-toggle>
196+
<mat-button-toggle
197+
value="legacy"
198+
(click)="reconciler.set('legacy')"
199+
>legacy
200+
</mat-button-toggle>
201+
</mat-button-toggle-group>
202+
<button mat-raised-button (click)="triggerChangeSet.next()">
203+
ChangeSet
204+
</button>
205+
<button mat-raised-button (click)="triggerMoveSet.next()">
206+
MoveSet
207+
</button>
208+
<button mat-raised-button (click)="triggerMoveSetSwapped.next()">
209+
MoveSet Swapped
210+
</button>
211+
</div>
196212
</div>
197-
</div>
213+
<div class="row">
214+
<div class="col-sm-12">
215+
<div>
216+
<input
217+
type="text"
218+
placeholder="filter"
219+
#searchInput
220+
(input)="filter$.next(searchInput.value)"
221+
/>
222+
</div>
223+
<p *rxLet="rendered$; let rendered">
224+
<strong>Rendered</strong> {{ rendered }}
225+
</p>
226+
<!--<p *rxLet="viewBroken$; let viewBroken">
227+
<ng-container>
228+
<span [ngStyle]="{ color: viewBroken ? 'red' : 'green' }"
229+
>VIEW BROKEN {{ viewBroken }}</span
230+
>
231+
</ng-container>
232+
</p>-->
233+
</div>
234+
</div>
235+
</ng-container>
198236
<div class="d-flex flex-column justify-content-start w-100">
199237
<div
200238
class="work-container d-flex flex-wrap w-100"
201239
[class.list-view]="viewMode === 'list'"
202240
*rxLet="view; let viewMode"
203241
>
204-
<div
205-
#workChild
206-
class="work-child d-flex"
207-
*rxFor="
208-
let a of data$;
209-
let index = index;
210-
let count = count;
211-
let even = even;
212-
let odd = odd;
213-
let first = first;
214-
let last = last;
215-
renderCallback: renderCallback;
216-
trackBy: trackById;
217-
strategy: strategy$
218-
"
219-
[title]="a.id + '_' + index + '_' + count"
220-
[class.even]="even"
221-
>
222-
<div class="child-bg" [ngStyle]="{ background: color(a) }"></div>
223-
<!--<div class="child-bg" [class.even]="even"></div>-->
224-
<div class="child-context flex-column flex-wrap">
225-
<button (click)="clickMe()">click me</button>
226-
<!--<small>{{ a }}</small>-->
227-
<small>id: {{ a.id }}</small>
228-
<small>value: {{ a.value }}</small>
229-
<small>index: {{ index }}</small>
230-
<small>count: {{ count }}</small>
231-
<small>even: {{ even }}</small>
232-
<small>odd: {{ odd }}</small>
233-
<small>first: {{ first }}</small>
234-
<small>last: {{ last }}</small>
235-
</div>
236-
</div>
242+
@if (reconciler() === 'experimental') {
243+
<ng-container provideExperimentalReconciliation>
244+
<div
245+
#workChild
246+
class="work-child d-flex"
247+
*rxFor="
248+
let a of data$;
249+
let index = index;
250+
let count = count;
251+
let even = even;
252+
let odd = odd;
253+
let first = first;
254+
let last = last;
255+
renderCallback: renderCallback;
256+
trackBy: trackById;
257+
strategy: strategy$
258+
"
259+
[title]="a.id + '_' + index + '_' + count"
260+
[class.even]="even"
261+
>
262+
<list-action-item>
263+
<div
264+
class="child-bg"
265+
[ngStyle]="{ background: color(a) }"
266+
></div>
267+
<!--<div class="child-bg" [class.even]="even"></div>-->
268+
<div class="child-context flex-column flex-wrap">
269+
<button (click)="clickMe()">click me</button>
270+
<!--<small>{{ a }}</small>-->
271+
<small>id: {{ a.id }}</small>
272+
<small>value: {{ a.value }}</small>
273+
<small>index: {{ index }}</small>
274+
<small>count: {{ count }}</small>
275+
<small>even: {{ even }}</small>
276+
<small>odd: {{ odd }}</small>
277+
<small>first: {{ first }}</small>
278+
<small>last: {{ last }}</small>
279+
</div>
280+
</list-action-item>
281+
</div>
282+
</ng-container>
283+
} @else {
284+
<ng-container provideLegacyReconciliation>
285+
<div
286+
#workChild
287+
class="work-child d-flex"
288+
*rxFor="
289+
let a of data$;
290+
let index = index;
291+
let count = count;
292+
let even = even;
293+
let odd = odd;
294+
let first = first;
295+
let last = last;
296+
renderCallback: renderCallback;
297+
trackBy: trackById;
298+
strategy: strategy$
299+
"
300+
[title]="a.id + '_' + index + '_' + count"
301+
[class.even]="even"
302+
>
303+
<list-action-item>
304+
<div
305+
class="child-bg"
306+
[ngStyle]="{ background: color(a) }"
307+
></div>
308+
<!--<div class="child-bg" [class.even]="even"></div>-->
309+
<div class="child-context flex-column flex-wrap">
310+
<button (click)="clickMe()">click me</button>
311+
<!--<small>{{ a }}</small>-->
312+
<small>id: {{ a.id }}</small>
313+
<small>value: {{ a.value }}</small>
314+
<small>index: {{ index }}</small>
315+
<small>count: {{ count }}</small>
316+
<small>even: {{ even }}</small>
317+
<small>odd: {{ odd }}</small>
318+
<small>first: {{ first }}</small>
319+
<small>last: {{ last }}</small>
320+
</div>
321+
</list-action-item>
322+
</div>
323+
</ng-container>
324+
}
237325
</div>
238326
</div>
239327
</rxa-visualizer>
240328
`,
241-
changeDetection: environment.changeDetection,
329+
changeDetection: ChangeDetectionStrategy.OnPush,
242330
encapsulation: ViewEncapsulation.None,
243331
providers: [ArrayProviderService],
244332
styles: [
@@ -291,18 +379,24 @@ const moveChangeSet1 = [items5k];
291379
.work-child .child-bg.even {
292380
background-color: red;
293381
}
382+
.work-child.broken {
383+
outline: 3px solid red;
384+
}
294385
`,
295386
],
296387
standalone: false,
297388
})
298389
export class ListActionsComponent extends Hooks implements AfterViewInit {
299-
@ViewChild('arrayP', { read: ArrayProviderComponent, static: true }) arrayP;
390+
@ViewChild('arrayP', { read: ArrayProviderComponent, static: true })
391+
arrayP: ArrayProviderComponent;
300392

301393
@ViewChildren('workChild') workChildren: QueryList<ElementRef<HTMLElement>>;
302394

303395
private numRendered = 0;
304396

305397
readonly view = new BehaviorSubject<'list' | 'tile'>('list');
398+
readonly reconciler = signal<'experimental' | 'legacy'>('experimental');
399+
readonly filter$ = new BehaviorSubject<string>('');
306400
readonly triggerChangeSet = new Subject<void>();
307401
readonly activeChangeSet$ = this.triggerChangeSet.pipe(
308402
switchMapTo(scheduled(customChangeSet, asyncScheduler)),
@@ -317,11 +411,21 @@ export class ListActionsComponent extends Hooks implements AfterViewInit {
317411
);
318412

319413
readonly data$ = defer(() =>
320-
merge(this.arrayP.array$, this.activeChangeSet$, this.activeMoveSet$),
321-
);
414+
combineLatest([
415+
merge(this.arrayP.array$, this.activeChangeSet$, this.activeMoveSet$),
416+
this.filter$,
417+
]).pipe(
418+
map(([items, search]) => {
419+
return items.filter((item) =>
420+
(item.value * 100).toString().startsWith(search),
421+
);
422+
}),
423+
),
424+
).pipe(shareReplay(1));
322425
readonly renderCallback = new Subject();
323426
readonly rendered$ = this.renderCallback.pipe(map(() => ++this.numRendered));
324427
readonly viewBroken$ = this.renderCallback.pipe(
428+
coalesceWith(scheduled([], asyncScheduler), (this.cdRef as any).context),
325429
map(() => {
326430
const children = Array.from(
327431
document.getElementsByClassName('work-child'),
@@ -335,6 +439,7 @@ export class ListActionsComponent extends Hooks implements AfterViewInit {
335439
(!even && child.classList.contains('even'))
336440
) {
337441
broken = true;
442+
child.classList.add('broken');
338443
break;
339444
}
340445
i++;

0 commit comments

Comments
 (0)