如何在Angular 4中从Controller访问排序管道数组(使用* ngFor和管道生成)

时间:2017-10-10 23:56:53

标签: angular angular-pipe

如何访问控制器内* ngFor中声明的变量?

我的代码如下:

<song *ngFor="let track of music | async | sortMusic: [sortBy] as sortedTracks" [trackInfo]="track" (click)="toggleTrack(track)"></song>

我想访问“sortedTracks”变量。我有兴趣从具有上述代码的组件访问它,而不是从歌曲组件控制器访问它。

1 个答案:

答案 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)
            ^^^^^
  • ngForOfexample)的扩展形式:
<ng-template #someId 
   let-track 
   ngFor 
   [ngForOf]="music | async | sortMusic: sortBy" 
   let-sortedTracks="ngFor">
  <song [trackInfo]="track"></song>
</ng-template>
  • 带有特殊选择器的指令(example
@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] ]'
})

没有工作。