Skip to content

Commit e87d85f

Browse files
Refactoring CustomValueAccessor implementation
1 parent 9ea5c92 commit e87d85f

File tree

2 files changed

+45
-42
lines changed

2 files changed

+45
-42
lines changed

templates/component.tst

Lines changed: 32 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
<# var implementedInterfaces = ['OnDestroy']; #>
77
<# !it.isExtension && implementedInterfaces.push('AfterViewInit'); #>
8+
<# it.isEditor && implementedInterfaces.push('ControlValueAccessor'); #>
89
<# collectionProperties.length && implementedInterfaces.push('OnChanges', 'DoCheck'); #>
910

1011
import {
@@ -17,7 +18,6 @@ import {
1718
OnDestroy<#? !it.isExtension #>,
1819
AfterViewInit<#?#><#? it.isEditor #>,
1920
ContentChild,
20-
Directive,
2121
forwardRef,
2222
HostListener<#?#><#? collectionProperties.length #>,
2323
OnChanges,
@@ -48,13 +48,22 @@ import { WatcherHelper } from '../core/watcher-helper';
4848
<#~ collectionNestedComponents :component:i #>import { <#= component.className #>Component } from './nested/<#= component.path #>';
4949
<#~#>
5050

51+
<#? it.isEditor #>
52+
53+
const CUSTOM_VALUE_ACCESSOR = {
54+
provide: NG_VALUE_ACCESSOR,
55+
useExisting: forwardRef(() => <#= it.className #>Component),
56+
multi: true
57+
};<#?#>
58+
5159
@Component({
52-
selector: '<#= it.selector #>',
60+
selector: '<#= it.selector #><#? it.isEditor #>, <#= it.selector #>[formControlName],<#= it.selector #>[formControl],<#= it.selector #>[ngModel]<#?#>',
5361
template: '<#? it.isTranscludedContent #><ng-content></ng-content><#?#>',<#? it.isViz #>
5462
styles: [ ' :host { display: block; }'],<#?#>
5563
providers: [
5664
DxTemplateHost,
57-
WatcherHelper,
65+
WatcherHelper,<#? it.isEditor #>
66+
CUSTOM_VALUE_ACCESSOR,<#?#>
5867
NestedOptionHost<#? collectionProperties.length #>,
5968
IterableDifferHelper<#?#>
6069
]
@@ -63,8 +72,8 @@ export class <#= it.className #>Component extends <#= baseClass #> <#? implement
6372
instance: <#= it.className #>;
6473
<#? it.isEditor #>
6574
@ContentChild(DxValidatorComponent)
66-
validator: DxValidatorComponent;<#?#>
67-
75+
validator: DxValidatorComponent;
76+
<#?#>
6877
<#~ it.properties :prop:i #>@Input()
6978
get <#= prop.name #>(): any {
7079
return this._getOption('<#= prop.name #>');
@@ -78,6 +87,10 @@ export class <#= it.className #>Component extends <#= baseClass #> <#? implement
7887
<#~ it.events :event:i #>@Output() <#= event.emit #>;<#? i < it.events.length-1 #>
7988
<#?#><#~#>
8089

90+
<#? it.isEditor #>
91+
@HostListener('valueChange', ['$event']) change(_) { }
92+
touched = () => {};<#?#>
93+
8194
<#~ collectionNestedComponents :component:i #>
8295
@ContentChildren(<#= component.className #>Component)
8396
get <#= component.propertyName #>Children(): QueryList<<#= component.className #>Component> {
@@ -110,7 +123,18 @@ export class <#= it.className #>Component extends <#= baseClass #> <#? implement
110123
}
111124
return widget;<#?#><#? !it.isEditor #>return new <#= it.className #>(element, options);<#?#>
112125
}
113-
126+
<#? it.isEditor #>
127+
writeValue(value: any): void {
128+
this.value = value;
129+
}
130+
<#? it.widgetName !== "dxRangeSelector" #>
131+
setDisabledState(isDisabled: boolean): void {
132+
this.disabled = isDisabled;
133+
}
134+
<#?#>
135+
registerOnChange(fn: (_: any) => void): void { this.change = fn; }
136+
registerOnTouched(fn: () => void): void { this.touched = fn; }
137+
<#?#>
114138
ngOnDestroy() {
115139
this._destroyWidget();
116140
}
@@ -129,50 +153,17 @@ export class <#= it.className #>Component extends <#= baseClass #> <#? implement
129153
}<#?#>
130154
}
131155

132-
<#? it.isEditor #>
133-
134-
const CUSTOM_VALUE_ACCESSOR = {
135-
provide: NG_VALUE_ACCESSOR,
136-
useExisting: forwardRef(() => <#= it.className #>ValueAccessorDirective),
137-
multi: true
138-
};
139-
140-
@Directive({
141-
selector: '<#= it.selector #>[formControlName],<#= it.selector #>[formControl],<#= it.selector #>[ngModel]',
142-
providers: [CUSTOM_VALUE_ACCESSOR]
143-
})
144-
export class <#= it.className #>ValueAccessorDirective implements ControlValueAccessor {
145-
@HostListener('valueChange', ['$event']) onChange(_) { }
146-
onTouched = () => {};
147-
148-
constructor(private host: <#= it.className #>Component) { }
149-
150-
writeValue(value: any): void {
151-
this.host.value = value;
152-
}
153-
<#? it.widgetName !== "dxRangeSelector" #>
154-
setDisabledState(isDisabled: boolean): void {
155-
this.host.disabled = isDisabled;
156-
}<#?#>
157-
158-
registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
159-
registerOnTouched(fn: () => void): void { this.onTouched = fn; }
160-
}
161-
<#?#>
162-
163156
@NgModule({
164157
imports: [<#~ it.nestedComponents :component:i #>
165158
<#= component.className #>Module,<#~#>
166159
DxTemplateModule
167160
],
168161
declarations: [
169-
<#= it.className #>Component<#? it.isEditor #>,
170-
<#= it.className #>ValueAccessorDirective<#?#>
162+
<#= it.className #>Component
171163
],
172164
exports: [
173165
<#= it.className #>Component<#~ it.nestedComponents :component:i #>,
174-
<#= component.className #>Module<#~#>,<#? it.isEditor #>
175-
<#= it.className #>ValueAccessorDirective,<#?#>
166+
<#= component.className #>Module<#~#>,
176167
DxTemplateModule
177168
],
178169
})

tests/src/ui/custom-value-accessor-implementation.spec.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,14 @@ import {
2828
template: `
2929
<form [formGroup]="form">
3030
<div class="form-group">
31-
<dx-text-box formControlName="formControl"></dx-text-box>
31+
<dx-text-box formControlName="formControl" [(ngModel)]="value"></dx-text-box>
3232
</div>
3333
</form>
3434
`
3535
})
3636
class TestContainerComponent implements OnInit {
3737
form: FormGroup;
38+
value = '';
3839
formControl: AbstractControl;
3940

4041
ngOnInit() {
@@ -77,4 +78,15 @@ describe('DxTextBox value accessor', () => {
7778

7879
expect(instance.option('disabled')).toBe(false);
7980
}));
81+
it('should change the value', async(() => {
82+
let fixture = TestBed.createComponent(TestContainerComponent);
83+
fixture.detectChanges();
84+
85+
let instance = getWidget(fixture);
86+
87+
fixture.componentInstance.value = 'text';
88+
fixture.detectChanges();
89+
90+
expect(instance.option('value')).toBe('text');
91+
}));
8092
});

0 commit comments

Comments
 (0)