mirror of
https://github.com/Raghu-Ch/angular-challenges.git
synced 2026-02-10 21:03:03 -05:00
feat(challenge36): add solution on trackby
This commit is contained in:
@@ -3,7 +3,7 @@ import { Component } from '@angular/core';
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [],
|
||||
selector: 'lib-root',
|
||||
selector: 'app-root',
|
||||
template: ``,
|
||||
styles: [''],
|
||||
})
|
||||
|
||||
@@ -51,7 +51,7 @@ export async function challengeGenerator(tree: Tree, options: Schema) {
|
||||
tmpl: '',
|
||||
projectName: names(options.name).name,
|
||||
title: options.title,
|
||||
challengeNumber,
|
||||
challengeNumber: challengeNumber + 1,
|
||||
docRepository: options.docRepository,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Tree, formatFiles } from '@nx/devkit';
|
||||
import { readFile, writeFile } from 'fs/promises';
|
||||
|
||||
const README_FILENAME = 'README.md';
|
||||
const OMIT = ['memoized', 'projection', 'testing-table', 'testing-forms'];
|
||||
@@ -46,10 +45,10 @@ function findHref(href) {
|
||||
|
||||
async function rewriteFile(tree: Tree, file: string) {
|
||||
console.log('Current file', file);
|
||||
const buffer = await readFile(file, { encoding: 'utf-8' });
|
||||
const buffer = tree.read(file);
|
||||
|
||||
const regex = new RegExp(/Answer:(\d+)/);
|
||||
const match = buffer.match(regex);
|
||||
const match = buffer.toString().match(regex);
|
||||
|
||||
if (!match) throw new Error('NO MATCH');
|
||||
|
||||
@@ -69,19 +68,19 @@ async function rewriteFile(tree: Tree, file: string) {
|
||||
-2
|
||||
)}/${pathElts.at(-1)}/`;
|
||||
|
||||
const doc = await readFile(docFile, { encoding: 'utf-8' });
|
||||
const doc = tree.read(docFile);
|
||||
|
||||
const regexTitle = new RegExp(/title:\s(🟢|🟠|🔴)\s(.+?)\n/);
|
||||
const matchTitle = doc.match(regexTitle);
|
||||
const matchTitle = doc.toString().match(regexTitle);
|
||||
const title = matchTitle[2];
|
||||
|
||||
const regexCommand = new RegExp(/npx nx serve\s(.+?)`\s/);
|
||||
const matchCommand = buffer.match(regexCommand);
|
||||
const matchCommand = buffer.toString().match(regexCommand);
|
||||
|
||||
let command = '';
|
||||
if (!matchCommand) {
|
||||
const regexOldCommand = new RegExp(/nx serve\s(.+?)\*/);
|
||||
command = buffer.match(regexOldCommand)[1];
|
||||
command = buffer.toString().match(regexOldCommand)[1];
|
||||
} else {
|
||||
command = matchCommand[1];
|
||||
}
|
||||
@@ -103,12 +102,12 @@ npx nx serve ${command}
|
||||
Challenge documentation is [here](${link}).
|
||||
`;
|
||||
|
||||
await writeFile(file, finalText, { encoding: 'utf-8' });
|
||||
tree.write(file, finalText);
|
||||
|
||||
///**** */
|
||||
|
||||
const regexHref = new RegExp(/<a href=("|')(.+?)("|')/, 'g');
|
||||
const href = buffer.match(regexHref).map(findHref);
|
||||
const href = buffer.toString().match(regexHref).map(findHref);
|
||||
|
||||
console.log('HREF', href);
|
||||
|
||||
@@ -150,21 +149,21 @@ Your PR title must start with <b>Answer:${number}</b>.
|
||||
}
|
||||
|
||||
const regexHeader = new RegExp(/([\s\S]*?)\s:::note/);
|
||||
const header = doc.match(regexHeader)[1];
|
||||
const header = doc.toString().match(regexHeader)[1];
|
||||
|
||||
console.log('header', header);
|
||||
|
||||
const regexContent = new RegExp(
|
||||
/Author: Thomas Laforge([\s\S]*?)### Submitting your work/
|
||||
);
|
||||
const matchContent = buffer.match(regexContent);
|
||||
const matchContent = buffer.toString().match(regexContent);
|
||||
|
||||
let content = '';
|
||||
if (!matchContent) {
|
||||
const regexOldContent = new RegExp(
|
||||
/Author: Thomas Laforge([\s\S]*?)## Submitting your work/
|
||||
);
|
||||
content = buffer.match(regexOldContent)[1];
|
||||
content = buffer.toString().match(regexOldContent)[1];
|
||||
} else {
|
||||
content = matchContent[1];
|
||||
}
|
||||
@@ -184,7 +183,7 @@ ${content}
|
||||
${footerText}
|
||||
`;
|
||||
|
||||
await writeFile(docFile, fullDocText, { encoding: 'utf-8' });
|
||||
tree.write(docFile, fullDocText);
|
||||
}
|
||||
|
||||
export async function readmeGenerator(tree: Tree) {
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export * from './lib/cd-flashing.directive';
|
||||
export { NgForTrackByModule } from './lib/track-by.directive';
|
||||
|
||||
51
libs/shared/directives/src/lib/track-by.directive.ts
Normal file
51
libs/shared/directives/src/lib/track-by.directive.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
/* eslint-disable @angular-eslint/directive-selector */
|
||||
import { NgFor, NgForOf } from '@angular/common';
|
||||
import {
|
||||
Directive,
|
||||
Input,
|
||||
NgIterable,
|
||||
NgModule,
|
||||
Provider,
|
||||
inject,
|
||||
} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[ngForTrackByProp]',
|
||||
standalone: true,
|
||||
})
|
||||
export class NgForTrackByPropDirective<T> {
|
||||
@Input() ngForOf!: NgIterable<T>;
|
||||
|
||||
@Input()
|
||||
set ngForTrackByProp(ngForTrackBy: keyof T) {
|
||||
// setter
|
||||
this.ngFor.ngForTrackBy = (index: number, item: T) => item[ngForTrackBy];
|
||||
}
|
||||
|
||||
private ngFor = inject(NgForOf<T>, { self: true });
|
||||
}
|
||||
|
||||
@Directive({
|
||||
selector: '[ngForTrackById]',
|
||||
standalone: true,
|
||||
})
|
||||
export class NgForTrackByIdDirective<T extends { id: string | number }> {
|
||||
@Input() ngForOf!: NgIterable<T>; // 2
|
||||
|
||||
private ngFor = inject(NgForOf<T>, { self: true }); // 3
|
||||
|
||||
constructor() {
|
||||
this.ngFor.ngForTrackBy = (index: number, item: T) => item.id; // 4
|
||||
}
|
||||
}
|
||||
|
||||
export const NgForTrackByDirective: Provider[] = [
|
||||
NgForTrackByIdDirective,
|
||||
NgForTrackByPropDirective,
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [NgFor, NgForTrackByDirective],
|
||||
exports: [NgFor, NgForTrackByDirective],
|
||||
})
|
||||
export class NgForTrackByModule {}
|
||||
Reference in New Issue
Block a user