【问题标题】:ViewChildren in dynamically rendered reactive form showing "undefined"ViewChildren 以动态呈现的反应形式显示“未定义”
【发布时间】:2019-04-03 16:11:53
【问题描述】:

我试图弄清楚如何动态呈现表单,然后使用@ViewChildren 循环遍历每个元素。但是,查询似乎没有找到任何东西,因为我在以下代码底部的ngAfterViewInit 中得到了一个零长度数组。 (作为参考,这里是 Stackblitz:https://angular-4lqtap.stackblitz.io)。我找到了几篇与此主题相关的文章,但都没有解决我面临的问题。

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 } from './hello.component';

@NgModule({
  imports:      [ BrowserModule, FormsModule, ReactiveFormsModule ],
  declarations: [ AppComponent, HelloComponent ],
  bootstrap:    [ AppComponent ],
  schemas: [NO_ERRORS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { }

【问题讨论】:

  • 您是否尝试过模板中的#foo 而不是输入中的foo?
  • 我试过了,可惜没用。
  • 取得一些进展。 . .将 NO_ERRORS_SCHEMA 和 CUSTOM_ELEMENTS_SCHEMA 添加到 App-Module 中的 @NgModule.schemas,并添加了 AfterViewInit 钩子。通过这些更改,我消除了 this.id 未定义错误,但不幸的是,forEach 循环中仍然没有发生任何事情。所以越来越近了,但还有一些工作要做。 . .任何想法,请分享!谢了!

标签: angular


【解决方案1】:

您需要做一些更改:

你需要在app.module.ts中添加declarations中的指令。

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>

ViewChildren 可以使用类而不是选择器,所以你应该改变这一行:

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

到:

@ViewChildren(IdVar) id: QueryList<IdVar>;  

另外注意,你真的不需要指令中额外的 []

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

我在 stackblitz 上复制了您的示例,并对其进行了一些修改以使其正常工作。 我还更改了指令的名称,以明确它是指令。

此处的示例:

https://stackblitz.com/edit/angular-directive-viewchildren?file=src%2Fapp%2Fhello.component.ts

【讨论】:

  • 谢谢@Daniel Piñeiro。您的解决方案完美运行!
  • 。 .关于您关于“将指令用作组件”的观点,我使用了代码并发现:selector: 'foo' 您可以使用“指令作为组件”(自定义组件),即&lt;foo id="i". . . &gt;,但如果:selector: '[foo]' (带方括号),则指令变为“属性指令”,如 &lt;input foo id="i" . . . &gt; 。 . .有趣的是,这两者是互斥的,所以使用方括号的查询只选择&lt;input&gt;,没有方括号的只有&lt;foo&gt;。 . .再次感谢大家的大力帮助!!
猜你喜欢
  • 2021-12-03
  • 2022-07-27
  • 1970-01-01
  • 2020-03-22
  • 2018-12-29
  • 1970-01-01
  • 2020-09-27
  • 2021-10-29
  • 1970-01-01
相关资源
最近更新 更多