首页 文章

关于ngForm和ngModel在角度模板驱动形式中的概念

提问于
浏览
0

你好我最近冒险进行角度和离子发展 .

我理解插值和属性绑定是将数据从类传递到模板,并且插值仅支持字符串,而属性绑定支持所有类型 .

事件绑定用于将数据从模板传递到类 .

使用foll实现双向绑定 . 4种方式:

  • 使用ngModel香蕉语法:

<input [(ngModel)] =“username”>

<p>您好{{username}}!</ p>

  • 没有香蕉语法的NgModel:

<input [ngModel] =“username”(ngModelChange)=“username = $ event”>

<p>您好{{username}}!</ p>

  • 没有ngModel:

<input [value] =“username”(输入)=“username = $ event.target.value”>

<p>您好{{username}}!</ p>

要么

<input [value] =“username”(输入)=“username = varTest.value”#varTest>

<p>您好{{username}}!</ p>

  • 我们可以实现自定义双向绑定(没有ngModel),前提是我们实现了适当的功能:

<custom-counter [(counter)] =“someValue”> </ custom-counter>

<p> counterValue = {{someValue}} </ p>

我们还有模板引用变量的概念 . 当您在输入字段上声明它时,可以使用插值在模板中访问字段的值 . 此外,如果将ngModel分配给模板ref变量..#varTref =“ngModel”,则可以使用插值在模板中访问元素的各种属性,如validation,dirty,pristine,touch,untouched . 所有这些都可以通过传递模板引用变量来传递给代码类文件,例如按钮单击事件或者我们可以使用ViewChild概念 .

我的问题是关于形式(模板驱动形式)的ngForms和ngModel概念:

  • 我们使用 <form #f="ngForm"..... 然后在每个输入元素中我们使用带名称的ngModel,这使得它可以作为forms.value.fieldname的属性访问 . 是否可以通过使用模板引用变量然后将其传递给按钮单击事件来实现相同的事情,从而可以访问代码中的表单元素?那为什么我们必须使用ngForm概念?

  • 在元素级别,我们使用ngModel . 这与属性绑定或事件绑定相同吗?或者只是让元素可以被#f访问?我们还可以使用模板引用变量来实现同样的不是吗?为了实现双向绑定,我们也在这里使用香蕉语法,那么在每个元素级别使用关键字ngModel真正用于模板驱动形式的目的是什么?

  • 使用[(ngModel)] = varName与写[(ngModel)] name = varName相同吗?

我需要清楚一点 . 谢谢 .

1 回答

  • 3

    是的,这些概念起初可能会令人困惑 . 但是您在上面指定的有关双向绑定的一些信息是不正确的:

    Two-way binding

    [(ngModel)]="lastName"

    对组件属性的任何修改都显示在模板中,并且模板中的任何更改都在组件属性中设置 . 这通常用于输入框和模板驱动表单 .

    以上是这个的“捷径”版本:

    <input [ngModel]="lastName" (ngModelChange)="lastName = $event">

    One way/property binding

    [ngModel]="lastName"

    UI与组件属性的值保持同步 . 这个类似于插值: {{lastName}}

    One time binding

    ngModel="lastName"

    仅绑定组件属性的初始值,如果值更改,则不会更改 .

    Template Reference Variables

    #lastNameVar="ngModel"    /* for a form model element eg input element*/
    #f="ngForm"               /* for the form itself */
    

    模板引用变量的主要用途是提供对模板中项目的引用 . 您不需要将它添加到模板驱动表单上的每个输入元素,只需要添加到您要访问的那些元素 .

    例如:

    <div class="form-group row mb-2">
        <label class="col-md-2 col-form-label"
               for="lastNameId">Last Name</label>
        <div class="col-md-8">
          <input class="form-control"
                 id="lastNameId"
                 type="text"
                 placeholder="Last Name (required)"
                 required
                 maxlength="50"
                 [(ngModel)]="customer.lastName"
                 name="lastName"
                 #lastNameVar="ngModel"
                 [ngClass]="{'is-invalid': (lastNameVar.touched || lastNameVar.dirty) && !lastNameVar.valid }" />
          <span class="invalid-feedback">
            <span *ngIf="lastNameVar.errors?.required">
              Please enter your last name.
            </span>
            <span *ngIf="lastNameVar.errors?.maxlength">
              The last name must be less than 50 characters.
            </span>
          </span>
        </div>
      </div>
    

    注意上面如何将模板引用变量设置为 #lastName ,然后使用它来设置样式(使用 [ngClass] )并检查错误集合以显示相应的错误消息 .

    或者对于表单的示例,您可以检查表单状态以禁用“保存”按钮,例如:

    <button class="btn btn-primary"
                  type="submit"
                  [disabled]="!f.valid">
            Save
          </button>
    

    如果您不需要访问模板中表单的状态,则不需要模板引用变量 .

    您还可以将表单的模板引用变量传递给组件以访问表单值或状态:

    在模板中:

    <form novalidate
          (ngSubmit)="save(signupForm)"
          #signupForm="ngForm">
    

    在组件中:

    save(customerForm: NgForm) {
        console.log('Saved: ' + JSON.stringify(customerForm.value));
      }
    

    您可以改为传递每个单独的控件's template reference variable, but why? As you add controls over time, you' d必须记住始终将其添加到方法调用中 . 而你_91624_的状态而不仅仅是形式的整体状态 . 简单地将引用传递给表单更容易/更好/更清楚 .

    <form novalidate
          (ngSubmit)="save(lastName, firstName, phone, email)">
    

相关问题