如何在 angular 的自定义指令中解码现有的结构指令字符串语法
How to decode existing structural directive string syntax in our custom directive in angular
就像我说的,我想在自定义指令中使用现有的基于结构指令字符串的语法
<element *ngFor='let x of array;let last = last;'></element>
我没有找到任何详细的文档,我们如何在我们的自定义结构指令中解码上述语法。我知道我们可以将此语法与所有结构指令 *xyz 一起使用,但我总是使用 [xyz] 代替。我试图找到 angular 官方文档,但一无所获。
所以我进入他们的代码以理解 *NgFor in github,除了他们如何解码语法外,我什么都懂了。
如果您看到如下所示的选择器
@Directive({selector: '[ngFor][ngForOf]'})
@Input()
set ngForTrackBy(fn: TrackByFunction<T>) {
//definition
}
并且所有输入方法都以选择器前缀开头,例如 ngForTrackBy。仅此而已吗?我们必须遵循选择器前缀吗?
如果是,那么我们可以用这种基于前缀的方法做些什么?如果不是,那么正确的方法是什么?
编译器的工作是匹配使用 let
语法定义的变量和传递到嵌入式视图的上下文。您可以定义任意多个变量,但如果您不通过上下文传递它们的值,它们的值将是未定义的。
我在这里使用自定义 my
指令并使用 let
语法定义两个变量 a
和 b
:
<ng-template my let-a=a let-b=b let-c=c>
<span>inside my, a is {{a}}, b is {{b}}, c is undefined: {{c === undefined}}</span>
</ng-template>
然后在描述指令时,我将具有变量值的上下文传递给嵌入式视图:
import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[my]'
})
export class MyDirective {
constructor(public vc: ViewContainerRef, public t: TemplateRef<any>) {
}
ngOnInit() {
const t = this.vc.createEmbeddedView(this.t, {a: 3, b: 4});
}
}
ngForOf
指令同理,here's how the context查找:
export class NgForOfContext<T, U extends NgIterable<T> = NgIterable<T>> {
constructor(public $implicit: T, public ngForOf: U, public index: number, public count: number) {}
get first(): boolean {
return this.index === 0;
}
get last(): boolean {
return this.index === this.count - 1;
}
get even(): boolean {
return this.index % 2 === 0;
}
get odd(): boolean {
return !this.even;
}
}
您还可以将 shorthand 语法与自定义指令一起使用:
<span *my="let a=a; let b=b; let c=c;">inside my, a is {{a}}, b is {{b}}, c is undefined: {{c === undefined}}</span>
就像我说的,我想在自定义指令中使用现有的基于结构指令字符串的语法
<element *ngFor='let x of array;let last = last;'></element>
我没有找到任何详细的文档,我们如何在我们的自定义结构指令中解码上述语法。我知道我们可以将此语法与所有结构指令 *xyz 一起使用,但我总是使用 [xyz] 代替。我试图找到 angular 官方文档,但一无所获。
所以我进入他们的代码以理解 *NgFor in github,除了他们如何解码语法外,我什么都懂了。
如果您看到如下所示的选择器
@Directive({selector: '[ngFor][ngForOf]'})
@Input()
set ngForTrackBy(fn: TrackByFunction<T>) {
//definition
}
并且所有输入方法都以选择器前缀开头,例如 ngForTrackBy。仅此而已吗?我们必须遵循选择器前缀吗?
如果是,那么我们可以用这种基于前缀的方法做些什么?如果不是,那么正确的方法是什么?
编译器的工作是匹配使用 let
语法定义的变量和传递到嵌入式视图的上下文。您可以定义任意多个变量,但如果您不通过上下文传递它们的值,它们的值将是未定义的。
我在这里使用自定义 my
指令并使用 let
语法定义两个变量 a
和 b
:
<ng-template my let-a=a let-b=b let-c=c>
<span>inside my, a is {{a}}, b is {{b}}, c is undefined: {{c === undefined}}</span>
</ng-template>
然后在描述指令时,我将具有变量值的上下文传递给嵌入式视图:
import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[my]'
})
export class MyDirective {
constructor(public vc: ViewContainerRef, public t: TemplateRef<any>) {
}
ngOnInit() {
const t = this.vc.createEmbeddedView(this.t, {a: 3, b: 4});
}
}
ngForOf
指令同理,here's how the context查找:
export class NgForOfContext<T, U extends NgIterable<T> = NgIterable<T>> {
constructor(public $implicit: T, public ngForOf: U, public index: number, public count: number) {}
get first(): boolean {
return this.index === 0;
}
get last(): boolean {
return this.index === this.count - 1;
}
get even(): boolean {
return this.index % 2 === 0;
}
get odd(): boolean {
return !this.even;
}
}
您还可以将 shorthand 语法与自定义指令一起使用:
<span *my="let a=a; let b=b; let c=c;">inside my, a is {{a}}, b is {{b}}, c is undefined: {{c === undefined}}</span>