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

时间:2018-03-29 17:39:24

标签: javascript angular angular-ng-if

单击提交按钮时出现异常Error TypeError and Error Context。如果我将删除ngIf指令它将作为例外,Full 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

感谢您提供任何帮助:)

2 个答案:

答案 0 :(得分:2)

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

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

或者你可以确保你的onSubmit中的HTML元素firstPlayer和secondePlayer返回HTMLObject。

在您的组件中,执行以下操作:

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

在您的HTML模板中,使用以下内容更改(ngSubmit)

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

如果结果是校正,你会得到......

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

...进入控制台。

如果确实未定义,请使用[ngModel]="firstPlayer"并检查错误是否仍然存在。

答案 1 :(得分:2)

模板引用变量可以在模板中的任何位置访问,因此文档清楚地说明了。 This article 非常有助于了解结构化指令会发生什么,在本例中是*ngIf

*ngIf会发生什么,它会创建自己的模板,因此模板引用可以在模板中访问,模板由*ngIf创建,只在该范围内。

以下摘自网站:

  

抛出错误的示例代码:

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

原因是ngIf指令 - 或与星号(*)一起使用的任何其他指令。这些指令被称为结构指令,而星形只是一种更复杂的简短形式。每次使用结构指令(ngIf,ngFor,ngSwitchCase,...)时,Angular的视图引擎都会将两个步骤中的星形(它将语法糖除去)转移到以下最终形式(使用前面的ngIf作为示例):

<ng-template [ngIf]="true">
...
</ng-template>`
     你注意到了吗?在包含结构指令的前一个HTML中出现了一些非同寻常的东西 - ng-template节点。此节点是将模板引用变量的范围仅限于此内部DOM部分的原因 - 它在内部定义了一个新模板。由于将变量限制在其定义模板中,因此在ng-template中定义的任何变量(这意味着在ngIf的DOM部分内)都不能在其外部使用。它不能跨越模板的边界。

但是如何解决你的潜在问题,即获取价值......你几乎已经设置了模板驱动的表单,所以你可以这样做,或者然后采取被动的方式:)