【问题标题】:Why template reference variable using ngModel is undefined inside a for-loop?为什么在 for 循环中未定义使用 ngModel 的模板引用变量?
【发布时间】:2019-07-29 07:01:22
【问题描述】:

我正在尝试在 HTML 模板中获取一个 DOM 元素来禁用/启用 表单按钮基于输入值并使用ngModel:#Custom_FirstName="ngModel"。输入是分隔组件中的自定义字段。

我的问题是元素 Custom_FirstName 始终是 undefined,我发现它与 For 循环 ngFor 有关。当我删除ngFor 时,错误已修复。但这并不能解决我的问题,因为我需要 for 循环,因为用户可以动态添加多个输入文本和 firstName 用户。

代码:

<div *ngFor="let el of users.departments.admins; let i=index; trackBy: trackByFn"
    <input-text [name]="'firstanme'"                                                             
                [(ngModel)]="el.firstName"                                                          
                [ngModelOptions]="{standalone: true}"                                                      
                [readonly]="false"                                                           
                [required]="true"
                labelText="First Name"
                #Custom_FirstName="ngModel">
    </input-text>
</div>

按钮:

&lt;button [disabled]="!Custom_FirstName.value || ....&gt;

我一直在检查official Doc,但找不到解决方法。任何提示如何解决此问题?

【问题讨论】:

  • 你不考虑使用响应式表单而不是模板表单吗?

标签: angular forms validation


【解决方案1】:

官方文档says

引用变量的范围是整个模板。所以,不要 在同一个模板中多次定义相同的变量名 运行时值将是不可预测的。

由于您已经将输入与数据绑定,只需跟踪数据即可。添加到您的组件中:

hasEmptyValue() {
    return users.departments.admins
        .some(admin => !admin.firstName || admin.firstName.length===0);
}

并在模板中进行更改:

<button [disabled]="hasEmptyValue() || ....>

【讨论】:

  • 谢谢。但是admin 来自哪里?我想你的意思是admins 复数。 !admin.firstName || admin.firstName.length===0。并且 IDE 还显示以下错误:“属性长度不存在于类型 'boolean'”
  • 如果我要使用它来根据索引拥有不同的变量,它也不起作用。 #Custom_FirstName[i]="ngModel"
  • @k.vincent admin 是我们传递给some() 的函数的参数。答案的第一版有错误。 some() 返回 boolean。所以它绝对不需要lenght。我已经更正了代码。
  • @k.vincent 关于admin 来自哪里的问题:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 是的,是的。但这只是一个错字。在我的代码中是正确的。我用括号来称呼它。无论如何,现在它在使用具有相同想法的 2 个函数时也可以正常工作。因为我的代码中的第二个字段也是一个数组。所以它意味着另一个数组中的数组。文档 Mozilla 很好。竖起大拇指。
【解决方案2】:

在 Angular 中,模板引用变量的范围仅限于定义它们的模板。所以基本上你只能在 div 中使用每个 #Custom_FirstName*ngFor,而不是在它之外。如果您不使用*ngFor,则范围会增加到整个文档,因此您不会得到undefined

为了解决您的问题,我建议您将代码包装在 &lt;form&gt; 标记中并获取表单的模板引用并检查表单的有效性以禁用按钮:

<form #myForm="ngForm">
  <div *ngFor="let el of users.departments.admins; let i=index; trackBy: trackByFn">
    <input-text [name]="'firstanme'"                                                             
                [(ngModel)]="el.firstName"                                                    
                [readonly]="false"                                                           
                [required]="true"
                labelText="First Name">
    </input-text>
  </div>
</form>

您的按钮将是:

<button [disabled]="myForm.invalid">

另外,请确保将 FormsModule 添加到您的模块导入中。

【讨论】:

  • 这行不通,因为我必须使用[ngModelOptions]="{standalone: true}" 无论如何我确实试了一下。没有机会。
  • @k.vincent 啊,是的,如果你需要独立选项,它不会工作!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-20
  • 1970-01-01
  • 2011-11-25
  • 1970-01-01
相关资源
最近更新 更多