【问题标题】:Validate input inside a ngFor using template driven forms使用模板驱动表单验证 ngFor 中的输入
【发布时间】:2017-12-08 09:12:55
【问题描述】:

在我们的 Angular 表单中(我们使用 template driven forms),我们有一个动态呈现的输入字段列表,因此,我们需要验证。在此之后:Using template driven form with dynamic input list (ngFor) 我没有再进一步,因为它似乎已经过时,因为 plunkr 示例不起作用。

那是我们的 tbody 呈现我们的列表:

  <tbody>
    <tr *ngFor="let item of items; let i=index">
      <td><span>{{ item.categoryName }}</span></td>
      <td class="text-right">
        <input *ngIf="editMode" 
          type="number" 
          tabindex="1" 
          autocomplete="off" 
          [(ngModel)]="item.value" name="value-{{item.categoryId}}" #value="ngModel"
          required 
        />
        {{value.valid}} <!--As I'm using ngForm I was expecting to receive false or true here-->
        <span *ngIf="!editMode">{{ item.value }}</span>
      </td>
      <td>
        <app-status [status]="item.status"></app-status>
      </td>
    </tr>
  </tbody>

这个工作正常,可以看到列表,但是验证不起作用。

如果我尝试:{{value.valid}} 我收到以下错误:

ERROR TypeError: Cannot read property 'valid' of undefined

意味着,我的 ngModel 实例不起作用。

我错过了什么?

【问题讨论】:

  • 这里的问题可能是模板引用变量。每个输入框都有 same 模板引用变量。根据文档:The scope of a reference variable is the entire template. Do not define the same variable name more than once in the same template. The runtime value will be unpredictable. 来自:angular.io/guide/…
  • 我没明白你的意思
  • 对于每个输入框,您都定义了一个value 变量,但是该变量的范围并不与输入框隔离,它可以被模板的整个范围引用。因此,特别是在您循环并在模板中分别创建这些内容的情况下,可能会在此过程中出现问题,因此会发出警告:
  • #value 是一个模板引用变量。您正在将具有此 same 名称的模板引用变量添加到 every 输入框。根据文档,您不应在模板中多次使用相同的模板引用变量。
  • 如果我有迭代,解决方案是什么?创建一个范围函数来为我验证我的价值?那么就不需要required 属性了吗?

标签: angular validation


【解决方案1】:

你想在哪里做{{value.valid}}?我在这里看不到,所以我不知道是什么导致了 null 的值定义。

除了使用value 的属性,您还可以在组件中使用一个函数来为您进行验证检查。

<tr *ngFor="let item of items; let i = index">
  <!-- somewhere in your code -->
  <div *ngIf="myValidationFunction(value)">
    <!-- stuff -->
  </div> 

然后在你的 ts 文件中,你可以有一些东西来检查它。如果它总是需要,那很简单。

myValidationFunction(value) {
    if (value) {
        // results to 'true' if value isn't null
        return value.valid; // where valid is some field in value
    }
    else { // if value is null, you can say that it is wrong
        return false; // this means that it will not be valid until it's defined
    }

【讨论】:

  • 这是一个很好的解决方案,那么使用 ngForm 到底有什么意义呢?几个小时以来,我一直在尝试用 angular 实现一个复杂的表单,但我不明白为什么这如此困难。根据您的 sn-p,我不会依赖 ngForm,我将拥有自己的验证功能。我将更新我的代码,以便您查看 {{value.valid}} 在哪里
  • 模板驱动的表单为简单明了的表单提供了简单明了的解决方案。对于更完整的表单(例如您的示例),请尝试改用 Reactive Forms。它们被设置为可以轻松地将任意数量的控件或控件组添加到您的表单中。
  • 我觉得使用表单可以生成更简洁、更易于维护的代码,特别是如果您使用他们的built in 表单内容。有很多开箱即用的功能,比如输入的最小/最大长度、必填字段等。我刚刚查了一下,似乎你可以定义自己的 ValidatorFn 类型的验证函数, 不管什么意思。我根本没有调查过,只是偶然发现的。
  • 要清楚一点...反应式表单还使用表单并利用所有内置验证,例如最小/最大长度、所需等。是的,您可以构建您的为模板驱动或响应式表单提供自己的验证器。
  • 我也尝试过响应式表单,一旦有了列表和子表单,这也不容易。我对反应式表单的问题是我在同一页面上有两个网格实例,它们共享相同的formArrayName,为了解决我必须将formArrayName 作为@Input 从孩子传递给父母,太可怕了!
猜你喜欢
  • 2017-02-02
  • 2017-01-29
  • 1970-01-01
  • 2017-05-31
  • 2018-01-13
  • 2019-04-16
  • 1970-01-01
  • 2018-07-10
相关资源
最近更新 更多