[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 ...
随机推荐
- DG观察日志传输
--primary端查询v$archived_log视图,确认日志是否被应用: set lines 300 pages 300 col name for a20 select name,dest_ ...
- CF-558E (线段树/分块)
解题思路: 很显然突破口就是字符集比较小,分块和线段树都能A 话说线段树时间是分块5倍啊 代码(线段树): #include<cstdio> #include<cstring> ...
- JS数组排序技巧汇总(冒泡、sort、快速、希尔等排序)
本文实例总结了JS数组排序技巧.分享给大家供大家参考,具体如下: 1.冒泡排序 var temp = 0; for (var i = 0; i < array.length; i++) { fo ...
- opera mini 7.5安卓改服版
opera mini 7.5安卓改服版Opera mini 7.5安卓版前两天发布了,试着进行改服实现***,过程跟以前的OPM7.0差不多,大家可参照我之前的博客教程Opera mini7.0改服教 ...
- 98.TCP通信传输文件
客户端 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include <stdlib.h> #include <s ...
- 【博客之星】CSDN2013博客之星--分析和预测
本文纯属个人见解,多有得罪啊! 具体结果,还是看最后CSDN给的结果吧! 昵称 名字 题材 质量 数量 知名度 预测 阳光岛主 杨刚 Python,Clojure,SAE 很高 346+ 很大 一定( ...
- 【例题 7-3 UVA - 10976】Fractions Again?!
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] x>=y => \(\frac{1}{x}<=\frac{1}{y}\) => \(\frac{1}{x}= ...
- LeetCode Algorithm 05_Longest Palindromic Substring
Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...
- fatfs输出目录
利用fatfs文件系统, 如何输出SD卡根目录下的各个文件夹名字呢? 程序如下: u8 Dirname_i; u8 Dirname_j; DIR dir; //读取txt里的目录用,还是要把fatfs ...
- (转)xshell无法在vim中复制黏贴
ssh xshell 连接在vim中无法用 ctrl+insert 复制黏贴 修改.vimrc set mouse=c vi的三种模式:命令模式,插入模式,可视模式.鼠标可以启动于各种模式中: The ...