Syed M. Taha (@smtaha512)
Software Engineer
@smtaha512
@smtaha512
@smtaha512
<div>
<img
class="star"
[ngClass]="{
disabled: isDisabled,
selected:
selectedRating?.star !== null &&
selectedRating?.star >= i
}"
*ngFor="let item of ratings; let i=index;"
src="/assets/star.svg"
(click)="onStarClick(item)"
/>
</div>
<p>{{ selectedRating?.text }}</p>
@smtaha512
@Component({
selector: 'app-rating',
templateUrl: './rating.component.html',
styleUrls: ['./rating.component.scss']
})
export class RatingComponent implements OnInit {
ratings = [
{ star: 0, text: 'Worst' },
{ star: 1, text: 'Bad' },
{ star: 2, text: 'Satisfactory' },
{ star: 3, text: 'Good' },
{ star: 4, text: 'Best' }
];
@Output() ratingChange = new EventEmitter();
selectedRating = this.ratings[0];
isDisabled: boolean;
constructor() {}
ngOnInit() {}
onStarClick(selectedRating: { star: number; text: string }) {
this.selectedRating = selectedRating;
this.ratingChange.emit(selectedRating.star);
}
}
@smtaha512
<app-rating (ratingChange)="onRatingChange($event)">
</app-rating>
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
private readonly form = new FormGroup({
rating: new FormControl()
});
onRatingChange(event) {
this.rating.setValue(event);
}
get rating() {
return this.form.get('rating');
}
}
@smtaha512
@smtaha512
@smtaha512
@smtaha512
@smtaha512
@Component({
selector: 'app-rating',
templateUrl: './rating.component.html',
styleUrls: ['./rating.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => RatingComponent),
multi: true
}
]
})
export class RatingComponent { }
@smtaha512
@smtaha512
interface ControlValueAccessor {
writeValue(obj: any): void;
registerOnChange(fn: any): void;
registerOnTouched(fn: any): void;
setDisabledState?(isDisabled: boolean): void;
}
@smtaha512
This method is called by the forms API to write to the view when programmatic changes from model to view are requested.
Native / Custom Input
CVA
Angular Form
writeValue(value)
Communication
interface
specific to
form control
writeValue(value: any): void
@smtaha512
registerOnChange(fn: (_: any) => void): void
This method is called by the forms API on initialization to update the form model when values propagate from the view to the model.
Native / Custom Input
CVA
Angular Form
registerOnChange(fn)
Communication
interface
specific to
form control
fn: (_: any) => void
@smtaha512
registerOnTouched(fn: any): void
This method is called by the forms API on initialization to update the form model on blur.
Native / Custom Input
CVA
Angular Form
registerOnTouched(fn)
Communication
interface
specific to
form control
fn: (_: any) => void
@smtaha512
setDisabledState?(isDisabled: boolean): void
Function that is called by the forms API when the control status changes to or from 'DISABLED'. Depending on the status, it enables or disables the appropriate DOM element.
Native / Custom Input
CVA
Angular Form
setDisabledState(isDisabled)
Communication
interface
specific to
form control
@smtaha512
@Component({})
export class RatingComponent implement ControlValueAccessor {
value: any;
disable: boolean;
onChange: any = () => { };
onTouched: any = () => { };
writeValue(obj: any): void {
this.value = obj;
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = onTouched;
}
setDisabledState?(isDisabled: boolean): void {
this.disabled = isDisabled;
}
}
@smtaha512
CVA Demo: https://github.com/smtaha512/cva-demo
The Control Value Accessor by Jennifer Wadella. (https://www.youtube.com/watch?v=kVbLSN0AW-Y&t=843s)
Angular Source Code. (github.com/angular/angular)
Angular documentation. (https://angular.io/api/forms/ControlValueAccessor)
@smtaha512
s.m.taha10@gmail.com