如何访问控制器内* ngFor中声明的变量?
我的代码如下:
<song *ngFor="let track of music | async | sortMusic: [sortBy] as sortedTracks" [trackInfo]="track" (click)="toggleTrack(track)"></song>
我想访问“sortedTracks”变量。我有兴趣从具有上述代码的组件访问它,而不是从歌曲组件控制器访问它。
答案 0 :(得分:2)
确实应该很容易:
@ViewChild(NgForOf) ngForDir: NgForOf<any>;
this.ngForDir.ngForOf
<强> Example 强>
旧版
1)特别指令
我们可以编写指令来帮助我获得它:
<强> ngfor-as.directive.ts 强>
import { Directive, EmbeddedViewRef, NgIterable, ViewContainerRef } from '@angular/core';
import { NgForOfContext } from '@angular/common';
@Directive({
selector: '[ngForOf]'
})
export class NgForOfAsDirective<T> {
constructor(private vcRef: ViewContainerRef) {}
public get asValue(): NgIterable<T> {
const viewRef = this.vcRef.get(0) as EmbeddedViewRef<NgForOfContext<T>>;
return viewRef ? viewRef.context.ngForOf : null;
}
}
一旦我们创建了上面的指令,我们就可以使用@ViewChild
来获取该指令的实例:
@Component({
selector: 'my-app',
template: `
<song *ngFor="let track of music | async | sortMusic: sortBy as sortedTracks" ...></song>
`
})
export class AppComponent {
...
@ViewChild(NgForOfAsDirective) ngForAs: NgForOfAsDirective<any[]>;
ngAfterViewInit() {
console.log(this.ngForAs.asValue);
}
}
<强> Stackblitz Example 强>
2)直接从ViewContainerRef获取价值
如果您不想创建指令,您可以抓住ViewContainer
指令使用的ngForOf
:
@Component({
selector: 'my-app',
template: `
<song *ngFor="let track of music | async | sortMusic: sortBy as sortedTracks" ...></song>
`
})
export class AppComponent {
@ViewChild(TemplateRef, { read: ViewContainerRef }) vcRef: ViewContainerRef;
get asMusicValue(): NgIterable<any> {
const viewRef = this.vcRef.get(0) as EmbeddedViewRef<NgForOfContext<any>>;
return viewRef ? viewRef.context.ngForOf : null;
}
...
ngAfterViewInit() {
console.log(this.asMusicValue);
}
}
<强> Stackblitz example 强>
当然,如果您的模板中有多个ngForOf
指令,那么在查询ViewContainerRef
时应该更加精确。
为此您可以使用以下选项之一:
@ViewChildren
如果知道确切的顺序(example)@ViewChildren(TemplateRef, { read: ViewContainerRef }) vcRefs: QueryList<ViewContainerRef>;
...
this.vcRefs.first.get(0)
^^^^^
ngForOf
(example)的扩展形式:<ng-template #someId
let-track
ngFor
[ngForOf]="music | async | sortMusic: sortBy"
let-sortedTracks="ngFor">
<song [trackInfo]="track"></song>
</ng-template>
@Directive({
selector: '[ngForOf=music | async | sortMusic: sortBy ]'
})
export class NgForOfMusic {}
...
@ViewChild(NgForOfMusic, { read: ViewContainerRef }) vcRef: ViewContainerRef;
匹配
*ngFor="let track of music | async | sortMusic: sortBy as sortedTracks"
| |
\ /
attrValue
但不要使用方括号,如:
*ngFor="let track of music | async | sortMusic: [sortBy] as sortedTracks"
因为选择器
@Directive({
selector: '[ngForOf=music | async | sortMusic: [sortBy] ]'
})
没有工作。