Angular ViewChildren以动态呈现的被动形式显示;“未定义”;

Angular ViewChildren以动态呈现的被动形式显示;“未定义”;,angular,Angular,我试图弄清楚如何动态呈现表单,然后使用@ViewChildren遍历每个元素。但是,查询似乎没有找到任何内容,因为我在下面代码底部的ngAfterViewInit中得到了一个零长度数组。(以下是Stackblitz:)供参考。我找到了几篇关于这个话题的文章,但没有一篇能解决我面临的问题 import { Directive, Component, Input, OnInit, AfterViewInit, AfterContentInit, ViewChild, ViewChildren, Co

我试图弄清楚如何动态呈现表单,然后使用@ViewChildren遍历每个元素。但是,查询似乎没有找到任何内容,因为我在下面代码底部的
ngAfterViewInit
中得到了一个零长度数组。(以下是Stackblitz:)供参考。我找到了几篇关于这个话题的文章,但没有一篇能解决我面临的问题

import { Directive, Component, Input, OnInit, AfterViewInit, AfterContentInit, ViewChild, ViewChildren, ContentChildren, QueryList } from '@angular/core';
import {FormGroup, FormControl} from '@angular/forms';

@Directive({selector: '[foo]'})
export class IdVar {
  // TODO(issue/24571): remove '!'.
  @Input() idString !: string;
}

@Component({
  selector: 'hello',
  template: `<h1>Hello {{name}}!</h1>
            <form #myForm="ngForm" [formGroup]="form">
              <ng-container *ngFor="let itm of testArr; let i = index"> 
              {{i}}: <input [foo] [id]="i" />
              <foo [idString]="i">{{i}}:&nbsp;</foo>
              </ng-container>
             </form>`,
  styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent implements OnInit, AfterViewInit  {

  @Input() name: string;
  form: FormGroup;
  formControls={};
  testArr = ["a", "b", "c"];
  @ViewChildren('foo') id: QueryList<IdVar>; 


  ngOnInit() {
    this.form = new FormGroup(this.formControls);
    this.testArr.forEach((itm)=>{
      this.formControls[itm] = new FormControl(itm);
      this.form.addControl(itm, this.formControls[itm]);
    })
  }

  ngAfterViewInit() {
    setTimeout(()=>console.log(this.id.length),1000);
  }

}


您需要做一些更改:

您需要在
app.module.ts
声明中添加指令

import { NgModule, NO_ERRORS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { HelloComponent, IdVar } from './hello.component';

@NgModule({
  imports:      [ BrowserModule, FormsModule, ReactiveFormsModule ],
  declarations: [ AppComponent, HelloComponent, IdVar ],
  bootstrap:    [ AppComponent ],
  schemas: [NO_ERRORS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { }
您正在使用指令作为组件,我认为您不需要这一行:

<foo [idString]="i">{{i}}:&nbsp;</foo>
{{i}}
ViewChildren与类一起工作,而不是与选择器一起工作,因此您应该更改行:

@ViewChildren('foo') id: QueryList<IdVar>; 
@ViewChildren('foo')id:QueryList;
致:

@ViewChildren(IdVar)id:QueryList;
另外,您实际上不需要指令中的额外[]

 <input foo [id]="i" />

我在stackblitz上介绍了您的示例,并对其进行了一些修改以使其生效。 我还更改了指令的名称,以明确它是一个指令

这里的实例:


您是否在模板中尝试了
#foo
,而不是在输入中尝试了
foo
?我尝试了,但不幸的是,它不起作用。正在取得一些进展。在App Module中的@NgModule.schemas中添加了无错误模式和自定义元素模式,并添加了AfterViewInit钩子。通过这些更改,我消除了
this.id
未定义的错误,但不幸的是,
forEach
循环中仍然没有发生任何事情。所以越来越近了,但还有一些工作要做。任何想法,请分享!Tks!谢谢你,丹尼尔·皮涅罗。您的解决方案非常有效。关于您关于“将指令用作组件”的观点,我对代码进行了研究,发现对于:
选择器:“foo”
您可以使用“directive as component”(自定义组件),即
,但如果:
选择器:“[foo]”
(带方括号),则该指令将变为“attribute directive”,如
所示。有趣的是,这两者是互斥的,因此使用方括号时,查询只拾取
,而不使用方括号时,查询只拾取
。再次感谢所有的帮助!!
@ViewChildren(IdVar) id: QueryList<IdVar>;  
 <input foo [id]="i" />