Skip to content

Commit

Permalink
feat: implement trackBy for angular (#1511)
Browse files Browse the repository at this point in the history
* implement trackBy for angular

* use indices so two fns with same forname dont clash

* changeset

* handle fors inside dynamic components

* trackBy should never call a fn
  • Loading branch information
sidmohanty11 authored Jul 31, 2024
1 parent 35606ea commit 9abf0ac
Show file tree
Hide file tree
Showing 9 changed files with 914 additions and 60 deletions.
5 changes: 5 additions & 0 deletions .changeset/witty-monkeys-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@builder.io/mitosis': patch
---

Feat: `trackBy` for angular (can be used when the child used inside <For> has a `key` attribute in mitosis)
156 changes: 148 additions & 8 deletions packages/core/src/__tests__/__snapshots__/angular.import.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1120,7 +1120,7 @@ import {
>
<ng-container *ngIf=\\"builderBlock && builderBlock.children\\">
<ng-container
*ngFor=\\"let block of builderBlock?.children; let index = index\\"
*ngFor=\\"let block of builderBlock?.children; let index = index; trackBy: trackByBlock0\\"
>
<BuilderBlockComponent
[block]=\\"block\\"
Expand Down Expand Up @@ -1407,6 +1407,9 @@ export default class FormComponent {
);
}
}
trackByBlock0(index, block) {
return block.id;
}
}

@NgModule({
Expand Down Expand Up @@ -2045,7 +2048,9 @@ import { kebabCase, snakeCase } from \\"lodash\\";
Submit
</button>
</ng-container>
<ng-container *ngFor=\\"let review of reviews; let index = index\\">
<ng-container
*ngFor=\\"let review of reviews; let index = index; trackBy: trackByReview0\\"
>
<div class=\\"review\\">
<img class=\\"img\\" [attr.src]=\\"review.avatar\\" />
<div [class]=\\"showReviewPrompt ? 'bg-primary' : 'bg-secondary'\\">
Expand Down Expand Up @@ -2101,6 +2106,9 @@ export default class SmileReviews {
snakeCaseValue() {
return snakeCase(\\"testThis\\");
}
trackByReview0(index, review) {
return review.id;
}

ngOnInit() {
if (typeof window !== \\"undefined\\") {
Expand Down Expand Up @@ -4104,7 +4112,9 @@ import RenderRepeatedBlock from \\"./render-repeated-block.lite\\";
></ng-container>
</ng-container>
<ng-container *ngIf=\\"!isEmptyHtmlElement(tag) && repeatItemData\\">
<ng-container *ngFor=\\"let data of repeatItemData; let index = index\\">
<ng-container
*ngFor=\\"let data of repeatItemData; let index = index; trackBy: trackByData0\\"
>
<render-repeated-block
[repeatContext]=\\"data.context\\"
[block]=\\"data.block\\"
Expand Down Expand Up @@ -4323,6 +4333,15 @@ export default class RenderBlock {
return RenderComponent;
}
}
trackByData0(index, data) {
return index;
}
trackByChild1(_, child) {
return \\"render-block-\\" + child.id;
}
trackByChild2(_, child) {
return \\"block-style-\\" + child.id;
}

constructor(private vcRef) {}

Expand Down Expand Up @@ -4642,7 +4661,9 @@ import { Component, Input } from \\"@angular/core\\";
selector: \\"nested-show, NestedShow\\",
template: \`
<ng-container *ngIf=\\"conditionA\\">
<ng-container *ngFor=\\"let item of items; let idx = index\\">
<ng-container
*ngFor=\\"let item of items; let idx = index; trackBy: trackByItem0\\"
>
<div>{{item}}</div>
</ng-container>
</ng-container>
Expand All @@ -4661,6 +4682,10 @@ import { Component, Input } from \\"@angular/core\\";
export default class NestedShow {
@Input() conditionA;
@Input() items;

trackByItem0(idx, item) {
return idx;
}
}

@NgModule({
Expand Down Expand Up @@ -5050,6 +5075,51 @@ export class SvgComponentModule {}
"
`;

exports[`Angular with Preserve Imports and File Extensions > jsx > Javascript Test > twoForsTrackBy 1`] = `
"import { NgModule } from \\"@angular/core\\";
import { CommonModule } from \\"@angular/common\\";

import { Component } from \\"@angular/core\\";

@Component({
selector: \\"my-component, MyComponent\\",
template: \`
<div>
<ng-container *ngFor=\\"let item of items; trackBy: trackByItem0\\">
<div>{{item}}</div>
</ng-container>
<ng-container *ngFor=\\"let item of items; trackBy: trackByItem1\\">
<div>{{item}}</div>
</ng-container>
</div>
\`,
styles: [
\`
:host {
display: contents;
}
\`,
],
})
export default class MyComponent {
items = [1, 2, 3];
trackByItem0(_, item) {
return item;
}
trackByItem1(_, item) {
return item;
}
}

@NgModule({
declarations: [MyComponent],
imports: [CommonModule],
exports: [MyComponent],
})
export class MyComponentModule {}
"
`;

exports[`Angular with Preserve Imports and File Extensions > jsx > Javascript Test > typeDependency 1`] = `
"import { NgModule } from \\"@angular/core\\";
import { CommonModule } from \\"@angular/common\\";
Expand Down Expand Up @@ -6524,7 +6594,7 @@ import {
>
<ng-container *ngIf=\\"builderBlock && builderBlock.children\\">
<ng-container
*ngFor=\\"let block of builderBlock?.children; let index = index\\"
*ngFor=\\"let block of builderBlock?.children; let index = index; trackBy: trackByBlock0\\"
>
<BuilderBlockComponent
[block]=\\"block\\"
Expand Down Expand Up @@ -6818,6 +6888,9 @@ export default class FormComponent {
);
}
}
trackByBlock0(index, block) {
return block.id;
}
}

@NgModule({
Expand Down Expand Up @@ -7552,7 +7625,9 @@ import { kebabCase, snakeCase } from \\"lodash\\";
Submit
</button>
</ng-container>
<ng-container *ngFor=\\"let review of reviews; let index = index\\">
<ng-container
*ngFor=\\"let review of reviews; let index = index; trackBy: trackByReview0\\"
>
<div class=\\"review\\">
<img class=\\"img\\" [attr.src]=\\"review.avatar\\" />
<div [class]=\\"showReviewPrompt ? 'bg-primary' : 'bg-secondary'\\">
Expand Down Expand Up @@ -7608,6 +7683,9 @@ export default class SmileReviews {
snakeCaseValue() {
return snakeCase(\\"testThis\\");
}
trackByReview0(index, review) {
return review.id;
}

ngOnInit() {
if (typeof window !== \\"undefined\\") {
Expand Down Expand Up @@ -9783,7 +9861,9 @@ import type { RepeatData } from \\"./types.js\\";
></ng-container>
</ng-container>
<ng-container *ngIf=\\"!isEmptyHtmlElement(tag) && repeatItemData\\">
<ng-container *ngFor=\\"let data of repeatItemData; let index = index\\">
<ng-container
*ngFor=\\"let data of repeatItemData; let index = index; trackBy: trackByData0\\"
>
<render-repeated-block
[repeatContext]=\\"data.context\\"
[block]=\\"data.block\\"
Expand Down Expand Up @@ -10002,6 +10082,15 @@ export default class RenderBlock {
return RenderComponent;
}
}
trackByData0(index, data) {
return index;
}
trackByChild1(_, child) {
return \\"render-block-\\" + child.id;
}
trackByChild2(_, child) {
return \\"block-style-\\" + child.id;
}

constructor(private vcRef: ViewContainerRef) {}

Expand Down Expand Up @@ -10350,7 +10439,9 @@ interface Props {
selector: \\"nested-show, NestedShow\\",
template: \`
<ng-container *ngIf=\\"conditionA\\">
<ng-container *ngFor=\\"let item of items; let idx = index\\">
<ng-container
*ngFor=\\"let item of items; let idx = index; trackBy: trackByItem0\\"
>
<div>{{item}}</div>
</ng-container>
</ng-container>
Expand All @@ -10369,6 +10460,10 @@ interface Props {
export default class NestedShow {
@Input() conditionA!: Props[\\"conditionA\\"];
@Input() items!: Props[\\"items\\"];

trackByItem0(idx, item) {
return idx;
}
}

@NgModule({
Expand Down Expand Up @@ -10775,6 +10870,51 @@ export class SvgComponentModule {}
"
`;

exports[`Angular with Preserve Imports and File Extensions > jsx > Typescript Test > twoForsTrackBy 1`] = `
"import { NgModule } from \\"@angular/core\\";
import { CommonModule } from \\"@angular/common\\";

import { Component } from \\"@angular/core\\";

@Component({
selector: \\"my-component, MyComponent\\",
template: \`
<div>
<ng-container *ngFor=\\"let item of items; trackBy: trackByItem0\\">
<div>{{item}}</div>
</ng-container>
<ng-container *ngFor=\\"let item of items; trackBy: trackByItem1\\">
<div>{{item}}</div>
</ng-container>
</div>
\`,
styles: [
\`
:host {
display: contents;
}
\`,
],
})
export default class MyComponent {
items = [1, 2, 3];
trackByItem0(_, item) {
return item;
}
trackByItem1(_, item) {
return item;
}
}

@NgModule({
declarations: [MyComponent],
imports: [CommonModule],
exports: [MyComponent],
})
export class MyComponentModule {}
"
`;

exports[`Angular with Preserve Imports and File Extensions > jsx > Typescript Test > typeDependency 1`] = `
"import { NgModule } from \\"@angular/core\\";
import { CommonModule } from \\"@angular/common\\";
Expand Down
Loading

0 comments on commit 9abf0ac

Please sign in to comment.