Skip to content

Commit b69d7a0

Browse files
Merge pull request #366 from dxvladislavvolkov/Template_refactoring
Refactoring CustomValueAccessor implementation
2 parents 9ea5c92 + 287e218 commit b69d7a0

File tree

2 files changed

+44
-42
lines changed

2 files changed

+44
-42
lines changed

templates/component.tst

Lines changed: 31 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
<#? it.isEditor #>/* tslint:disable:directive-selector */<#?#>
21
<# var collectionProperties = it.properties.filter(item => item.isCollection).map(item => item.name); #>
32
<# var collectionNestedComponents = it.nestedComponents.filter(item => item.isCollection && item.root); #>
43
<# var baseClass = it.isExtension ? 'DxComponentExtension' : 'DxComponent'; #>
54

65
<# var implementedInterfaces = ['OnDestroy']; #>
76
<# !it.isExtension && implementedInterfaces.push('AfterViewInit'); #>
7+
<# it.isEditor && implementedInterfaces.push('ControlValueAccessor'); #>
88
<# collectionProperties.length && implementedInterfaces.push('OnChanges', 'DoCheck'); #>
99

1010
import {
@@ -17,7 +17,6 @@ import {
1717
OnDestroy<#? !it.isExtension #>,
1818
AfterViewInit<#?#><#? it.isEditor #>,
1919
ContentChild,
20-
Directive,
2120
forwardRef,
2221
HostListener<#?#><#? collectionProperties.length #>,
2322
OnChanges,
@@ -48,13 +47,22 @@ import { WatcherHelper } from '../core/watcher-helper';
4847
<#~ collectionNestedComponents :component:i #>import { <#= component.className #>Component } from './nested/<#= component.path #>';
4948
<#~#>
5049

50+
<#? it.isEditor #>
51+
52+
const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
53+
provide: NG_VALUE_ACCESSOR,
54+
useExisting: forwardRef(() => <#= it.className #>Component),
55+
multi: true
56+
};<#?#>
57+
5158
@Component({
5259
selector: '<#= it.selector #>',
5360
template: '<#? it.isTranscludedContent #><ng-content></ng-content><#?#>',<#? it.isViz #>
5461
styles: [ ' :host { display: block; }'],<#?#>
5562
providers: [
5663
DxTemplateHost,
57-
WatcherHelper,
64+
WatcherHelper,<#? it.isEditor #>
65+
CUSTOM_VALUE_ACCESSOR_PROVIDER,<#?#>
5866
NestedOptionHost<#? collectionProperties.length #>,
5967
IterableDifferHelper<#?#>
6068
]
@@ -63,8 +71,8 @@ export class <#= it.className #>Component extends <#= baseClass #> <#? implement
6371
instance: <#= it.className #>;
6472
<#? it.isEditor #>
6573
@ContentChild(DxValidatorComponent)
66-
validator: DxValidatorComponent;<#?#>
67-
74+
validator: DxValidatorComponent;
75+
<#?#>
6876
<#~ it.properties :prop:i #>@Input()
6977
get <#= prop.name #>(): any {
7078
return this._getOption('<#= prop.name #>');
@@ -78,6 +86,10 @@ export class <#= it.className #>Component extends <#= baseClass #> <#? implement
7886
<#~ it.events :event:i #>@Output() <#= event.emit #>;<#? i < it.events.length-1 #>
7987
<#?#><#~#>
8088

89+
<#? it.isEditor #>
90+
@HostListener('valueChange', ['$event']) change(_) { }
91+
touched = () => {};<#?#>
92+
8193
<#~ collectionNestedComponents :component:i #>
8294
@ContentChildren(<#= component.className #>Component)
8395
get <#= component.propertyName #>Children(): QueryList<<#= component.className #>Component> {
@@ -110,7 +122,18 @@ export class <#= it.className #>Component extends <#= baseClass #> <#? implement
110122
}
111123
return widget;<#?#><#? !it.isEditor #>return new <#= it.className #>(element, options);<#?#>
112124
}
113-
125+
<#? it.isEditor #>
126+
writeValue(value: any): void {
127+
this.value = value;
128+
}
129+
<#? it.widgetName !== "dxRangeSelector" #>
130+
setDisabledState(isDisabled: boolean): void {
131+
this.disabled = isDisabled;
132+
}
133+
<#?#>
134+
registerOnChange(fn: (_: any) => void): void { this.change = fn; }
135+
registerOnTouched(fn: () => void): void { this.touched = fn; }
136+
<#?#>
114137
ngOnDestroy() {
115138
this._destroyWidget();
116139
}
@@ -129,50 +152,17 @@ export class <#= it.className #>Component extends <#= baseClass #> <#? implement
129152
}<#?#>
130153
}
131154

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-
163155
@NgModule({
164156
imports: [<#~ it.nestedComponents :component:i #>
165157
<#= component.className #>Module,<#~#>
166158
DxTemplateModule
167159
],
168160
declarations: [
169-
<#= it.className #>Component<#? it.isEditor #>,
170-
<#= it.className #>ValueAccessorDirective<#?#>
161+
<#= it.className #>Component
171162
],
172163
exports: [
173164
<#= it.className #>Component<#~ it.nestedComponents :component:i #>,
174-
<#= component.className #>Module<#~#>,<#? it.isEditor #>
175-
<#= it.className #>ValueAccessorDirective,<#?#>
165+
<#= component.className #>Module<#~#>,
176166
DxTemplateModule
177167
],
178168
})

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)