gpt4 book ai didi

具有严格类型检查的 Angular 全局 trackBy 属性指令

转载 作者:行者123 更新时间:2023-12-05 02:32:16 25 4
gpt4 key购买 nike

我想通过传递属性名称来跟踪 ngFor 项目来创建一个唯一的 trackBy 指令,这是代码:

import { NgForOf } from '@angular/common';
import { Directive, Host, Input } from '@angular/core';

@Directive({
selector: '[ngForTrackByProp]',
})
export class NgForTrackByPropDirective<T> {
private propertyName: keyof T;

constructor(@Host() public ngForOf: NgForOf<T>) {
this.ngForOf.ngForTrackBy = this.trackBy.bind(this);
}

trackBy(index: number, item: T) {
if (!this.propertyName) {
throw new Error(`Property name not defined`);
}
if (typeof item[this.propertyName] === 'undefined') {
throw new Error(`Property "${this.propertyName}" is undefined`);
}
const value = item[this.propertyName];
console.log(
`Item "${index}" trackByProp "${this.propertyName}" with value "${value}"`
);
return value;
}

@Input()
set ngForTrackByProp(value: keyof T) {
this.propertyName = value;
}

static ngTemplateContextGuard<T>(
dir: NgForTrackByPropDirective<T>,
ctx: any
): ctx is NgForTrackByPropDirective<T> {
return true;
}
}

用法:

import { Component } from '@angular/core';

@Component({
selector: 'my-app',
template: `
<ul *ngFor="let item of list; trackByProp: 'id'">
<li>{{ item.id }} {{ item.name }}</li>
</ul>`,
})
export class AppComponent {
list = [
{ id: 0, name: 'foo' },
{ id: 1, name: 'bar' },
{ id: 2, name: 'baz' },
];
}

这是 ONLINE DEMO

代码有效,但我想确保传递的属性是集合项的键,如果不是,则将错误设为编译错误,例如:

import { Component } from '@angular/core';

@Component({
selector: 'my-app',
template: `
<ul *ngFor="let item of list; trackByProp: 'XXXXXXXXXXXXX'">
<li>{{ item.id }} {{ item.name }}</li>
</ul>`,
})
export class AppComponent {
list = [
{ id: 0, name: 'foo' },
{ id: 1, name: 'bar' },
{ id: 2, name: 'baz' },
];
}

旁注,我的 tsconfig.json:

"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"strictTemplates": true,
"strictInjectionParameters": true
}

最佳答案

您可以通过定义 ngForOf @Input 属性来缩小传递数组中项目的类型:

import { NgIterable, ... } from '@angular/core';

...
export class NgForTrackByPropDirective<T> {

@Input() ngForOf: NgIterable<T>;

constructor(@Host() public ngForOfDir: NgForOf<T>) {
this.ngForOfDir.ngForTrackBy = this.trackBy.bind(this);
}
...

Forked Stackblitz

关于具有严格类型检查的 Angular 全局 trackBy 属性指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71309538/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com