From e87d85f6439f1c7024c2ab2e83f6dd85061f8bb9 Mon Sep 17 00:00:00 2001 From: "volkov.vladislav" Date: Fri, 27 Jan 2017 16:02:30 +0300 Subject: [PATCH 1/3] Refactoring CustomValueAccessor implementation --- templates/component.tst | 73 ++++++++----------- ...stom-value-accessor-implementation.spec.ts | 14 +++- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/templates/component.tst b/templates/component.tst index 08a6bdc44..06359322c 100644 --- a/templates/component.tst +++ b/templates/component.tst @@ -5,6 +5,7 @@ <# var implementedInterfaces = ['OnDestroy']; #> <# !it.isExtension && implementedInterfaces.push('AfterViewInit'); #> +<# it.isEditor && implementedInterfaces.push('ControlValueAccessor'); #> <# collectionProperties.length && implementedInterfaces.push('OnChanges', 'DoCheck'); #> import { @@ -17,7 +18,6 @@ import { OnDestroy<#? !it.isExtension #>, AfterViewInit<#?#><#? it.isEditor #>, ContentChild, - Directive, forwardRef, HostListener<#?#><#? collectionProperties.length #>, OnChanges, @@ -48,13 +48,22 @@ import { WatcherHelper } from '../core/watcher-helper'; <#~ collectionNestedComponents :component:i #>import { <#= component.className #>Component } from './nested/<#= component.path #>'; <#~#> +<#? it.isEditor #> + +const CUSTOM_VALUE_ACCESSOR = { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => <#= it.className #>Component), + multi: true +};<#?#> + @Component({ - selector: '<#= it.selector #>', + selector: '<#= it.selector #><#? it.isEditor #>, <#= it.selector #>[formControlName],<#= it.selector #>[formControl],<#= it.selector #>[ngModel]<#?#>', template: '<#? it.isTranscludedContent #><#?#>',<#? it.isViz #> styles: [ ' :host { display: block; }'],<#?#> providers: [ DxTemplateHost, - WatcherHelper, + WatcherHelper,<#? it.isEditor #> + CUSTOM_VALUE_ACCESSOR,<#?#> NestedOptionHost<#? collectionProperties.length #>, IterableDifferHelper<#?#> ] @@ -63,8 +72,8 @@ export class <#= it.className #>Component extends <#= baseClass #> <#? implement instance: <#= it.className #>; <#? it.isEditor #> @ContentChild(DxValidatorComponent) - validator: DxValidatorComponent;<#?#> - + validator: DxValidatorComponent; +<#?#> <#~ it.properties :prop:i #>@Input() get <#= prop.name #>(): any { return this._getOption('<#= prop.name #>'); @@ -78,6 +87,10 @@ export class <#= it.className #>Component extends <#= baseClass #> <#? implement <#~ it.events :event:i #>@Output() <#= event.emit #>;<#? i < it.events.length-1 #> <#?#><#~#> +<#? it.isEditor #> + @HostListener('valueChange', ['$event']) change(_) { } + touched = () => {};<#?#> + <#~ collectionNestedComponents :component:i #> @ContentChildren(<#= component.className #>Component) get <#= component.propertyName #>Children(): QueryList<<#= component.className #>Component> { @@ -110,7 +123,18 @@ export class <#= it.className #>Component extends <#= baseClass #> <#? implement } return widget;<#?#><#? !it.isEditor #>return new <#= it.className #>(element, options);<#?#> } - +<#? it.isEditor #> + writeValue(value: any): void { + this.value = value; + } +<#? it.widgetName !== "dxRangeSelector" #> + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + } +<#?#> + registerOnChange(fn: (_: any) => void): void { this.change = fn; } + registerOnTouched(fn: () => void): void { this.touched = fn; } +<#?#> ngOnDestroy() { this._destroyWidget(); } @@ -129,50 +153,17 @@ export class <#= it.className #>Component extends <#= baseClass #> <#? implement }<#?#> } -<#? it.isEditor #> - -const CUSTOM_VALUE_ACCESSOR = { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => <#= it.className #>ValueAccessorDirective), - multi: true -}; - -@Directive({ - selector: '<#= it.selector #>[formControlName],<#= it.selector #>[formControl],<#= it.selector #>[ngModel]', - providers: [CUSTOM_VALUE_ACCESSOR] -}) -export class <#= it.className #>ValueAccessorDirective implements ControlValueAccessor { - @HostListener('valueChange', ['$event']) onChange(_) { } - onTouched = () => {}; - - constructor(private host: <#= it.className #>Component) { } - - writeValue(value: any): void { - this.host.value = value; - } -<#? it.widgetName !== "dxRangeSelector" #> - setDisabledState(isDisabled: boolean): void { - this.host.disabled = isDisabled; - }<#?#> - - registerOnChange(fn: (_: any) => void): void { this.onChange = fn; } - registerOnTouched(fn: () => void): void { this.onTouched = fn; } -} -<#?#> - @NgModule({ imports: [<#~ it.nestedComponents :component:i #> <#= component.className #>Module,<#~#> DxTemplateModule ], declarations: [ - <#= it.className #>Component<#? it.isEditor #>, - <#= it.className #>ValueAccessorDirective<#?#> + <#= it.className #>Component ], exports: [ <#= it.className #>Component<#~ it.nestedComponents :component:i #>, - <#= component.className #>Module<#~#>,<#? it.isEditor #> - <#= it.className #>ValueAccessorDirective,<#?#> + <#= component.className #>Module<#~#>, DxTemplateModule ], }) diff --git a/tests/src/ui/custom-value-accessor-implementation.spec.ts b/tests/src/ui/custom-value-accessor-implementation.spec.ts index bbbf67f15..a8e8c649d 100644 --- a/tests/src/ui/custom-value-accessor-implementation.spec.ts +++ b/tests/src/ui/custom-value-accessor-implementation.spec.ts @@ -28,13 +28,14 @@ import { template: `
- +
` }) class TestContainerComponent implements OnInit { form: FormGroup; + value = ''; formControl: AbstractControl; ngOnInit() { @@ -77,4 +78,15 @@ describe('DxTextBox value accessor', () => { expect(instance.option('disabled')).toBe(false); })); + it('should change the value', async(() => { + let fixture = TestBed.createComponent(TestContainerComponent); + fixture.detectChanges(); + + let instance = getWidget(fixture); + + fixture.componentInstance.value = 'text'; + fixture.detectChanges(); + + expect(instance.option('value')).toBe('text'); + })); }); From 0da47aaa78b8ed309825ce9f385e95cc83919aea Mon Sep 17 00:00:00 2001 From: "volkov.vladislav" Date: Fri, 27 Jan 2017 16:46:28 +0300 Subject: [PATCH 2/3] Refactoring --- templates/component.tst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/component.tst b/templates/component.tst index 06359322c..d89bef7a9 100644 --- a/templates/component.tst +++ b/templates/component.tst @@ -50,20 +50,20 @@ import { WatcherHelper } from '../core/watcher-helper'; <#? it.isEditor #> -const CUSTOM_VALUE_ACCESSOR = { +const CUSTOM_VALUE_ACCESSOR_PROVIDER = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => <#= it.className #>Component), multi: true };<#?#> @Component({ - selector: '<#= it.selector #><#? it.isEditor #>, <#= it.selector #>[formControlName],<#= it.selector #>[formControl],<#= it.selector #>[ngModel]<#?#>', + selector: '<#= it.selector #>', template: '<#? it.isTranscludedContent #><#?#>',<#? it.isViz #> styles: [ ' :host { display: block; }'],<#?#> providers: [ DxTemplateHost, WatcherHelper,<#? it.isEditor #> - CUSTOM_VALUE_ACCESSOR,<#?#> + CUSTOM_VALUE_ACCESSOR_PROVIDER,<#?#> NestedOptionHost<#? collectionProperties.length #>, IterableDifferHelper<#?#> ] From 287e218cc1f3ad1dbecb378de92419f661babeb9 Mon Sep 17 00:00:00 2001 From: "volkov.vladislav" Date: Fri, 27 Jan 2017 17:44:14 +0300 Subject: [PATCH 3/3] Remove directive selector --- templates/component.tst | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/component.tst b/templates/component.tst index d89bef7a9..bae3be26d 100644 --- a/templates/component.tst +++ b/templates/component.tst @@ -1,4 +1,3 @@ -<#? it.isEditor #>/* tslint:disable:directive-selector */<#?#> <# var collectionProperties = it.properties.filter(item => item.isCollection).map(item => item.name); #> <# var collectionNestedComponents = it.nestedComponents.filter(item => item.isCollection && item.root); #> <# var baseClass = it.isExtension ? 'DxComponentExtension' : 'DxComponent'; #>