从具有 ngIf 指令的输入中获取值时出错

error in getting value from input that have ngIf directive

单击提交按钮时出现异常 Error TypeError and Error Context。如果我删除 ngIf 指令,它将正常工作,完整的 StackTrace:

PlayerNameFormComponent.html:8 ERROR TypeError: Cannot read property 'value' of undefined
at Object.eval [as handleEvent] (PlayerNameFormComponent.html:8)
at handleEvent (core.js:13547)
at callWithDebugContext (core.js:15056)
at Object.debugHandleEvent [as handleEvent] (core.js:14643)
at dispatchEvent (core.js:9962)
at eval (core.js:12301)
at SafeSubscriber.schedulerFn [as _next] (core.js:4343)
at SafeSubscriber.__tryOrUnsub (Subscriber.js:240)
at SafeSubscriber.next (Subscriber.js:187)
at Subscriber._next (Subscriber.js:128)

PlayerNameFormComponent.html

<form (ngSubmit)="onSubmit(firstPlayer.value, secondPlayer.value)"> // The line that throws the exception

  <div class="input-field col s6">
    <label for="firstPlayer">First Player Name</label>
    <input #firstPlayer id="firstPlayer" name="firstPlayer" type="text" class="validate">
  </div>

  <div *ngIf="isMultiplePlayers" class="input-field col s6">
    <label for="secondPlayer">Second Player Name</label>
    <input #secondPlayer id="secondPlayer" name="secondPlayer" type="text" class="validate">
  </div>

  <button type="submit" class="waves-effect waves-light btn">Start</button>
</form>

PlayerNameFormComponent.ts

export class PlayerNameFormComponent {
  isMultiplePlayers = true;

 public onSubmit(firstPlayer: string, secondPlayer: string) {
   console.log(firstPlayer);
   console.log(secondPlayer);
 }

}

编辑: 我将我的表单标签更改为 - <form (ngSubmit)="onSubmit(firstPlayer?.value, secondPlayer?.value)"> 现在它的打印是为了控制 firstPlayer 输入值而不是 secondPlayer 值它的打印 null

感谢您的帮助:)

您的问题并非来自您的 *ngIf。尝试使用 Elvis 运算符暂时删除错误:

onSubmit(firstPlayer?.value, secondPlayer?.value)

或者您可以确保在您的 onSubmit 中 HTML 元素 firstPlayer 和 secondePlayer return HTMLObject.

进入您的组件,执行此操作:

onSubmit(firstPlayer, secondPlayer) {
   console.log(firstPlayer, secondPlayer);
}

然后在您的 HTML 模板中,将 (ngSubmit) 行更改为:

<form (ngSubmit)="onSubmit(firstPlayer, secondPlayer)">

如果结果是更正,您将得到...

<input id="firstPlayer" name="firstPlayer" type="text" class="validate">
...

...进入控制台。

如果真的是undefined,使用[ngModel]="firstPlayer"检查是否还报错

模板引用变量可以在模板中的任何地方访问,所以文档说明得很清楚。 This article 非常有助于理解结构指令会发生什么,在这种情况下,您的 *ngIf.

*ngIf 会创建自己的模板,因此您的模板引用可以在模板内部访问,模板由 *ngIf 创建,并且只能在该范围内访问。

以下是网站摘录:

Sample code that throws error:

<div *ngIf="true">
  <my-component #variable [input]="'Do you see me?'>
</div>
{{ variable.input }}

The reason for this is the ngIf directive - or any other directive used together with a star (*). These directives are so called structural directives and the star is just a short form for something more complex. Every time you use a structural directive (ngIf, ngFor, ngSwitchCase, ...) Angular's view engine is desugaring (it removes the syntactical sugar) the star within two steps to the following final form (using the previous ngIf as an example):

<ng-template [ngIf]="true">
...
</ng-template>`

Did you notice? Something extraordinary emerged out of the previous HTML containing the structural directive - the ng-template node. This node is the reason for limiting the scope of the template reference variable to exactly this inner DOM part only - it defines a new template inside. Because of limiting a variable to its defining template any variable defined within the ng-template (and this means within the DOM part of the ngIf) cannot be used outside of it. It cannot cross the borders of a template.


但是如何解决您的潜在问题,即获取值...您几乎已经设置了一个 template-driven 表单,因此您可以这样做,或者然后采用被动方式:)