从具有 ngIf 指令的输入中获取值时出错 [英] error in getting value from input that have ngIf directive

查看:25
本文介绍了从具有 ngIf 指令的输入中获取值时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

单击提交按钮时出现异常Error TypeError and Error Context.如果我将删除 ngIf 指令它会像例外一样工作,完整的堆栈跟踪:

PlayerNameFormComponent.html:8 错误类型错误:无法读取未定义的属性值"在 Object.eval [as handleEvent] (PlayerNameFormComponent.html:8)在 handleEvent (core.js:13547)在 callWithDebugContext (core.js:15056)在 Object.debugHandleEvent [作为 handleEvent] (core.js:14643)在 dispatchEvent (core.js:9962)在 eval (core.js:12301)在 SafeSubscriber.schedulerFn [as _next] (core.js:4343)在 SafeSubscriber.__tryOrUnsub (Subscriber.js:240)在 SafeSubscriber.next (Subscriber.js:187)在 Subscriber._next (Subscriber.js:128)

PlayerNameFormComponent.html

//抛出异常的那一行<div class="input-field col s6"><label for="firstPlayer">第一玩家姓名</label><input #firstPlayer id="firstPlayer" name="firstPlayer" type="text" class="validate">

<div *ngIf="isMultiplePlayers" class="input-field col s6"><label for="secondPlayer">第二个玩家名称</label><input #secondPlayer id="secondPlayer" name="secondPlayer" type="text" class="validate">

<button type="submit" class="waves-effect wave-light btn">开始</button></表单>

PlayerNameFormComponent.ts

导出类 PlayerNameFormComponent {isMultiplePlayers = true;public onSubmit(firstPlayer: string, secondPlayer: string) {控制台日志(第一播放器);控制台日志(第二个播放器);}}

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

感谢您的任何帮助:)

解决方案

可以在模板中的任何位置访问模板引用变量,因此文档中明确说明.这篇文章 非常有助于理解结构指令会发生什么,在这种情况下是您的 *ngIf.

*ngIf 发生的事情是它创建了自己的模板,所以你的模板引用可以在模板内部访问,模板由 *ngIf 创建,并且只能在那个范围.

以下是网站摘录:

<块引用>

引发错误的示例代码:

<my-component #variable [input]="'你看到我了吗?'>

{{ 变量.输入 }}

这样做的原因是 ngIf 指令 - 或任何其他与星号 (*) 一起使用的指令.这些指令被称为结构指令,星号只是更复杂事物的缩写形式.每次使用结构指令(ngIf、ngFor、ngSwitchCase、...)时,Angular 的视图引擎都会在两步内将星号脱糖(它去除语法糖)到以下最终形式(以前面的 ngIf 为例):

...</ng-模板>`

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

<小时>

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

I get an exception Error TypeError and Error Context when the submit button is clicked. If I will delete the ngIf directive It will work as excepted, The 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);
 }

}

EDIT: I changed my form tag to - <form (ngSubmit)="onSubmit(firstPlayer?.value, secondPlayer?.value)"> and now its print to console the firstPlayer input value and instead of secondPlayer value its prints null

Thanks for any kind of help :)

解决方案

Template reference variables can be accessed anywhere in template, so the docs state clearly. This article is very helpful to understand what happens with structular directives, in this case your *ngIf.

What happens with the *ngIf is that it creates it's own template, so your template reference is accessible inside the template, the template created by *ngIf and only in that scope.

Here's excerpt from the website:

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.


But how to solve your underlying problem, i.e getting the values... You almost have a template-driven form set up already, so you could do that, or then go the reactive way :)

这篇关于从具有 ngIf 指令的输入中获取值时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆