[Angular] Implementing a ControlValueAccessor
So when you need to create a ControlValueAccessor?
When you want to use a custom component as form control. For example a counter component, you can custom the style and the way to control the value changes.

It needs some setup for control value accessor, but after you have done it once, you can prettty much just copy & paste the same template around to create a control value access.
import { Component, Input, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
const COUNTER_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => StockCounterComponent),
multi: true
};
@Component({
selector: 'stock-counter',
providers: [COUNTER_VALUE_ACCESSOR],
styleUrls: ['stock-counter.component.scss'],
template: `
...
`
})
export class StockCounterComponent implements ControlValueAccessor {
value: number;
writeValue(val: number) {
this.value = val;
}
registerOnChange(fn: any) {
this.onModelChange = fn;
}
registerOnTouched(fn: any) {
this.onTouch = fn;
}
...
}
So the template is somehow like the code above, highly recommend to create any snippet or live template in your IDE.
So inside the component we create, we have three methods,
- writeValue(obj: any)
- registerOnChange(fn: Function)
- registerOnTouched(fn: Function)
To understand each method is the key point to understand how control value access.
So first 'writeValue':
value: number;
writeValue(val: number) {
this.value = val;
}
This is for setting initial value, we take value from our form builder and pass to our component via 'writeValue'.
<stock-counter
[step]=""
[min]=""
[max]=""
formControlName="quantity">
So the value comes from 'formControlName="quantity"'.
Now at the point, you can think that our form holds a model value and our component also holds a view value.
We need to sync model value and view value.
The way to do that is by "registerOnChange":
registerOnChange(fn: any) {
this.onModelChange = fn;
}
increment() {
this.value = this.value === this.max ?
this.value :
this.value + this.step;
this.onModelChange(this.value);
}
Every time our view value (component value) changed, to need to notify our form about the changes, we need to call 'this.onModelChange(this.value)' function and pass in the changes value.
After this form will be able to the updated value.
OK, now we able to sync the value from our component to our form. But you might think about this can be easily done by EventEmitter, when border to create Control value accessor? The most important reason is that "Validation"!
html "form" component actually does lots of thing underhook. What example, it set field state "untouch", "touched", "dirty", "prinstin". We use those status to do validation and error messages.
For example:
input.ng-touched.ng-invalid {
border-left: 5px solid red;
}
If the field is touched and is invalid, we set the border to red.
Currently, we have our value synced, and control value access also helps us to add form validation ability to our component. But once the value changed, our component still show 'ng-untouch':

So we need "registerOnTouched" function to help us to do that:
registerOnTouched(fn: any) {
this.onTouch = fn;
}
increment() {
this.value = this.value === this.max ?
this.value :
this.value + this.step;
this.onModelChange(this.value);
this.onTouch();
}
Now after the value changed, our component will be set 'ng-touched', now we are fully conver our component to a form component.
[Angular] Implementing a ControlValueAccessor的更多相关文章
- [Angular] Implementing A General Communication Mechanism For Directive Interaction
We have modal implement and now we want to implement close functionality. Becuase we use a structure ...
- [Angular] Create a ng-true-value and ng-false-value in Angular by controlValueAccessor
If you're coming from AngularJS (v1.x) you probably remember the ng-true-value and ng-false-value di ...
- Angular写一个Form组件-TagInput
前端开发少不了和表单打交道; Angular中, 提供了强大的表单的支持, 响应式表单(Reactive Form) 和 模板驱动的表单(Template-driven Form) 的双向数据流给我们 ...
- Angular Forms - 自定义 ngModel 绑定值的方式
在 Angular 应用中,我们有两种方式来实现表单绑定--"模板驱动表单"与"响应式表单".这两种方式通常能够很好的处理大部分的情况,但是对于一些特殊的表单控 ...
- angular实现简单的pagination分页组件
不想使用第三方库,只想使用一个分页器,那么就简单的实现一个,效果如下: 1.使用方式: <custom-pagination *ngIf="enterpriseList.length& ...
- [AngularFire] Angular File Uploads to Firebase Storage with Angular control value accessor
The upload class will be used in the service layer. Notice it has a constructor for file attribute, ...
- [Angular] Implement a custom form component by using control value accessor
We have a form component: <label> <h3>Type</h3> <workout-type formControlName=& ...
- angular 响应式自定义表单控件—注册头像实例
1. 组件继承ControlValueAccessor,ControlValueAccessor接口需要实现三个必选方法 writeValue() 用于向元素中写入值,获取表单的元素的元素值 regi ...
- 表单-angular
模板表单: <form #myform="ngForm" (ngSubmit)="onsubmit(myform.value)" > <div ...
随机推荐
- powerdesigner 连接mysql提示“connection test failed”
powerdesigner 连接mysql提示“connection test failed”,该如何解决: 1.把64位的jdk换成32位的jdk(VM只支持32的jre) 2.系统变量: CL ...
- 洛谷 P1626 象棋比赛
P1626 象棋比赛 题目描述 有N个人要参加国际象棋比赛,该比赛要进行K场对弈.每个人最多参加两场对弈,最少参加零场对弈.每个人都有一个与其他人不相同的等级(用一个正整数来表示). 在对弈中,等级高 ...
- JavaBean对象转map
可能会经常使用的方法,利用反射将javaBean转换为map.稍作改动就可以转为想要的其它对象. /** * obj转map * @param map 转出的map * @param obj 须要转换 ...
- C#做完一个网站怎么发布?
前段时间在局域网上发布了一个自己做的网站,发布过程中遇到了不少问题.下面就发布过程和发布过程中遇到的问题与(你)大家一起分享一下,希望对(你)大家有所帮助吧! 在将ASP.NET网站发布到服务器之前需 ...
- 【河南省多校脸萌第六场 A】分班级
[链接]点击打开链接 [题意] 在这里写题意 [题解] 最大的给了最小的,实际上就对应了,最大值减1,最小值加1. 那么二分最后班级人数最小的最大可能是几->temp1; 二分最后班级人数最大的 ...
- LeetCode Algorithm 06_ZigZag Conversion
The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...
- Swiper+ ejs模板引擎+ iScroll插件知识总结
一. Swiper swiper是一个应用于移动端的动画插件,原理类似于轮播图 官网 http://www.swiper.com.cn/# html结构 <div class="swi ...
- liunx基本操作常用命令
liunx通常用作服务器,运行服务器软件,服务器要等待,类似超市学关键命令操作 内核,外壳 shell命令跟内核打交道用的是发行版本,不是内核,Radhat公司的CentOS,阿里巴巴也用这个 liu ...
- 【转】排列组合 "n个球放入m个盒子m"问题 总结
出处:https://blog.csdn.net/qwb492859377/article/details/50654627 球,盒子都可以分成是否不能区分,和能区分,还能分成是否能有空箱子,所以一共 ...
- Microsoft Bot Framework 链接至微信公共号
如何将 Microsoft Bot Framework 链接至微信公共号 说到 Microsoft Bot Framework 其实微软发布了已经有一段时间了,有很多朋友可能还不太了解,微软Bot ...