结构指令上下文可以包含函数吗?
Can a structural directive context contain a function?
我创建了一个简单的结构指令来帮助为一些自定义组件生成唯一的 ID。
import { Directive, DoCheck, Input, TemplateRef, ViewContainerRef } from '@angular/core';
import { v4 as uuid } from 'uuid';
export class UniqueIdContext {
constructor(private $implicit: string) {}
at(index: number) {
return `${this.$implicit}_${index}`;
}
}
@Directive({
selector: '[uniqueId]'
})
export class UniqueIdDirective implements DoCheck {
@Input()
set uniqueIdFor(uniqueIdFor: string) {
this._uniqueIdFor = uniqueIdFor;
this._uniqueIdDirty = true;
}
private _uniqueIdFor: string;
private _uniqueIdDirty = false;
constructor(
private templateRef: TemplateRef<UniqueIdContext>,
private viewContainerRef: ViewContainerRef
) {}
ngDoCheck(): void {
if (this._uniqueIdDirty) {
this._uniqueIdDirty = false;
const prefix = uuid();
const name = this._uniqueIdFor;
const id = `${prefix}_${name}`.replace(/-/g, '');
this.viewContainerRef.createEmbeddedView(
this.templateRef,
new UniqueIdContext(id)
);
}
}
}
用法如下:
<div *uniqueId="let id for 'control'">
<input [attr.id]="id" [formControl]="control">
<label [attr.for]="id">My Label</label>
</div>
如果我想按原样使用 id,这很有效。但是,我打算在 ngFor
循环中使用它来在每次迭代时为控件生成 id,它会将索引作为生成的 id 的后缀。这就是 UniqueIdContext.at()
函数的目的,但它似乎不起作用。
<ul *uniqueId="let id for 'control'">
<li *ngFor="let control of controls; index as i">
<input [attr.id]="at(i)" [formControl]="control">
<label [attr.for]="at(i)">My Label {{i}}</label>
</li>
</ul>
我也尝试了 id.at(i)
和 id(i)
但没有用。我想将所有内容都包含在 directive/context.
中
我需要以某种方式声明模板变量吗?我怎样才能完成这项工作?
所以看起来这里的主要限制是 this
的使用。我需要将该方法绑定到 this
,然后为其声明一个模板变量。
export class UniqueIdContext {
constructor(private $implicit: string) {
this.at = this.at.bind(this);
}
at(index?: number) {
return index != null ? `${this.$implicit}_${index}` : this.$implicit;
}
}
<ul *uniqueId="let id for 'control'; at as idAt">
<li *ngFor="let control of controls; index as i">
<input [attr.id]="idAt(i)" [formControl]="control">
<label [attr.for]="idAt(i)">My Label {{i}}</label>
</li>
</ul>
我创建了一个简单的结构指令来帮助为一些自定义组件生成唯一的 ID。
import { Directive, DoCheck, Input, TemplateRef, ViewContainerRef } from '@angular/core';
import { v4 as uuid } from 'uuid';
export class UniqueIdContext {
constructor(private $implicit: string) {}
at(index: number) {
return `${this.$implicit}_${index}`;
}
}
@Directive({
selector: '[uniqueId]'
})
export class UniqueIdDirective implements DoCheck {
@Input()
set uniqueIdFor(uniqueIdFor: string) {
this._uniqueIdFor = uniqueIdFor;
this._uniqueIdDirty = true;
}
private _uniqueIdFor: string;
private _uniqueIdDirty = false;
constructor(
private templateRef: TemplateRef<UniqueIdContext>,
private viewContainerRef: ViewContainerRef
) {}
ngDoCheck(): void {
if (this._uniqueIdDirty) {
this._uniqueIdDirty = false;
const prefix = uuid();
const name = this._uniqueIdFor;
const id = `${prefix}_${name}`.replace(/-/g, '');
this.viewContainerRef.createEmbeddedView(
this.templateRef,
new UniqueIdContext(id)
);
}
}
}
用法如下:
<div *uniqueId="let id for 'control'">
<input [attr.id]="id" [formControl]="control">
<label [attr.for]="id">My Label</label>
</div>
如果我想按原样使用 id,这很有效。但是,我打算在 ngFor
循环中使用它来在每次迭代时为控件生成 id,它会将索引作为生成的 id 的后缀。这就是 UniqueIdContext.at()
函数的目的,但它似乎不起作用。
<ul *uniqueId="let id for 'control'">
<li *ngFor="let control of controls; index as i">
<input [attr.id]="at(i)" [formControl]="control">
<label [attr.for]="at(i)">My Label {{i}}</label>
</li>
</ul>
我也尝试了 id.at(i)
和 id(i)
但没有用。我想将所有内容都包含在 directive/context.
我需要以某种方式声明模板变量吗?我怎样才能完成这项工作?
所以看起来这里的主要限制是 this
的使用。我需要将该方法绑定到 this
,然后为其声明一个模板变量。
export class UniqueIdContext {
constructor(private $implicit: string) {
this.at = this.at.bind(this);
}
at(index?: number) {
return index != null ? `${this.$implicit}_${index}` : this.$implicit;
}
}
<ul *uniqueId="let id for 'control'; at as idAt">
<li *ngFor="let control of controls; index as i">
<input [attr.id]="idAt(i)" [formControl]="control">
<label [attr.for]="idAt(i)">My Label {{i}}</label>
</li>
</ul>