详谈Angular 2+ 的表单(一)之模板驱动型表单(2)

ERROR Error: Uncaught (in promise): Error: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions.

ngModel 和 FormControl

假如我们使用的是 ngModel ,没有任何中括号小括号的话,这代表着我们创建了一个 FormControl 的实例,这个实例将会跟踪值的变化、用户的交互、验证状态以及保持视图和领域对象的同步等工作。

<input type="text" placeholder="请输入您的 email 地址" ngModel>

如果我们将这个控件放在一个 Form 表单中, ngModel 会自动将这个 FormControl 注册为 Form 的子控件。下面的例子中我们在 <form> 中加上了 ngForm 指令,声明这是一个 Angular 可识别的表单,而 ngModel 会将 <input> 注册成表单的子控件,这个子控件的名字就是 email ,而且 ngModel 会基于这个子控件的值去绑定表单的的值,这也是为什么需要显式声明 name 的原因。

其实在我们导入 FormsModule 的时候,所有的 <form> 标签都会默认的被认为是一个 NgForm ,因此我们并不需要显式的在标签中写 ngForm 这个指令。

<!-- ngForm 并不需要显示声明,任何 <form> 标签默认都是 ngForm --> <form novalidate ngForm> <input type="text" placeholder="请输入您的 email 地址" ngModel> </form>

这一切现在都是不可见的,所以大家可能还是有些困惑,那么下面我们将其“可视化”,这需要我们引用一下表单对象,所以我们使用 #f="ngForm" 以便我们可以在模版中输出表单的一些特性。

<!-- 使用 # 把表单对象导出到 f 这个可引用变量中 --> <form novalidate #f="ngForm"> ... </form> <!-- 将表单的值以 JSON 形式输出 --> {{f.value | json}}

这时如果我们在 email 中输入 sss ,可以看到下图的以 JSON 形式出现的表单值:

详谈Angular 2+ 的表单(一)之模板驱动型表单

 

控件的输入值同步到了表单的值中

单向数据绑定

那么接下来,我们看看 [ngModel] 有什么用?如果我们想给控件设置一个初始值怎么办呢,这时就需要进行一个单向绑定,方向是从组件到视图。我们可以做的是在初始化 User 的时候,将 email 属性设置成 wang@163.com

user: User = { email: 'wang@163.com', ... };

而且在模版中使用 [ngModel]="user.email" 进行单向绑定,这个语法其实和普通的属性绑定是一样的,用中括号标示这是一个要进行数据绑定的属性,等号右边是需要绑定的值(这里是 user.email )。那么我们就可以得到下面这样的输出了, email 的初始值被绑定成功!

单向数据绑定

 

双向数据绑定

但上面的例子存在一个问题,数据的绑定是单向的,也就是说,在输入框进行输入的时候,我们的 user 的值不会随之改变的。为了更好的说明,我们将 user 和 表单的值同时输出

<div> <span>user: </span> {{user | json}} </div> <div> <span>表单:</span> {{f.value | json}} </div>

此时我们将默认的电子邮件改成 wang@gmail.com 的话,表单的值是改变了,但 user 并未改变。

 

输入的值影响了表单,但不会影响领域对象

如果我们希望的是在输入时,这个输入的值也反向的影响我们的 user 对象的值的话,那就需要用到双向绑定了,也就是 [(ngModel)] 需要上场了。

详谈Angular 2+ 的表单(一)之模板驱动型表单

 

表单和领域对象的值保持了同步

无论如何,这个 [()] 表达真是很奇怪的样子,其实这个表达是一个语法糖。只要我们知道下面的两种写法是等价的,我们就会很清楚的理解了:用这个语法糖你就不用既写数据绑定又写事件绑定了。

<input [(ngModel)]="user.email"> <input [ngModel]="user.email"` (ngModelChange)="user.email = $event">

ngModelGroup 是什么鬼?

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wypgjd.html