Skip to content

Commit 5bbbbb8

Browse files
authored
Merge pull request #529 from DevExpress/rework_the_strategy_of_the_applying_options
Rework the strategy of applying options
2 parents 8ee05b2 + 48b6b37 commit 5bbbbb8

File tree

4 files changed

+82
-24
lines changed

4 files changed

+82
-24
lines changed

src/core/component.ts

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import {
22
ElementRef,
33
NgZone,
44
QueryList,
5-
AfterViewInit
5+
AfterViewInit,
6+
AfterContentChecked
67
} from '@angular/core';
78

89
import { DxTemplateDirective } from './template';
@@ -16,8 +17,8 @@ import {
1617
CollectionNestedOptionContainerImpl
1718
} from './nested-option';
1819

19-
export abstract class DxComponent implements AfterViewInit, INestedOptionContainer, ICollectionNestedOptionContainer {
20-
private _initialOptions: any;
20+
export abstract class DxComponent implements AfterViewInit, AfterContentChecked, INestedOptionContainer, ICollectionNestedOptionContainer {
21+
private _optionToUpdate: any = {};
2122
private _collectionContainerImpl: ICollectionNestedOptionContainer;
2223
eventHelper: EmitterHelper;
2324
templates: DxTemplateDirective[];
@@ -33,12 +34,12 @@ export abstract class DxComponent implements AfterViewInit, INestedOptionContain
3334
this.templates.forEach(template => {
3435
initialTemplates[template.name] = template;
3536
});
36-
this._initialOptions.integrationOptions.templates = initialTemplates;
37+
this._optionToUpdate.integrationOptions.templates = initialTemplates;
3738
}
3839
}
3940
private _initOptions() {
40-
this._initialOptions.eventsStrategy = this.eventHelper.strategy;
41-
this._initialOptions.integrationOptions.watchMethod = this.watcherHelper.getWatchMethod();
41+
this._optionToUpdate.eventsStrategy = this.eventHelper.strategy;
42+
this._optionToUpdate.integrationOptions.watchMethod = this.watcherHelper.getWatchMethod();
4243
}
4344
protected _createEventEmitters(events) {
4445
events.forEach(event => {
@@ -55,39 +56,32 @@ export abstract class DxComponent implements AfterViewInit, INestedOptionContain
5556
return true;
5657
}
5758
protected _getOption(name: string) {
58-
if (this.instance) {
59-
return this.instance.option(name);
60-
} else {
61-
return this._initialOptions[name];
62-
}
59+
return this.instance ?
60+
this.instance.option(name) :
61+
this._optionToUpdate[name];
6362
}
6463
protected _setOption(name: string, value: any) {
65-
if (this.instance) {
66-
this._updateOption(name, value);
67-
} else {
68-
this._initialOptions[name] = value;
69-
}
70-
}
71-
protected _updateOption(name: string, value: any) {
7264
if (this._shouldOptionChange(name, value)) {
73-
this.instance.option(name, value);
65+
this._optionToUpdate[name] = value;
7466
};
7567
}
7668
protected abstract _createInstance(element, options)
7769
protected _createWidget(element: any) {
7870
let events = [];
7971

72+
this._optionToUpdate.integrationOptions = {};
8073
this._initTemplates();
8174
this._initOptions();
8275

8376
let optionChangeHandler = function(e) {
8477
events.push(e.name);
8578
};
8679

87-
this._initialOptions.onInitializing = function() {
80+
this._optionToUpdate.onInitializing = function() {
8881
this.on('optionChanged', optionChangeHandler);
8982
};
90-
this.instance = this._createInstance(element, this._initialOptions);
83+
this.instance = this._createInstance(element, this._optionToUpdate);
84+
this._optionToUpdate = {};
9185

9286
this.instance.off('optionChanged', optionChangeHandler);
9387
this.instance.on('optionChanged', (e) => {
@@ -113,12 +107,17 @@ export abstract class DxComponent implements AfterViewInit, INestedOptionContain
113107
}
114108
}
115109
constructor(protected element: ElementRef, private ngZone: NgZone, templateHost: DxTemplateHost, private watcherHelper: WatcherHelper) {
116-
this._initialOptions = { integrationOptions: {} };
117110
this.templates = [];
118111
templateHost.setHost(this);
119112
this._collectionContainerImpl = new CollectionNestedOptionContainerImpl(this._setOption.bind(this));
120113
this.eventHelper = new EmitterHelper(this.ngZone, this);
121114
}
115+
ngAfterContentChecked() {
116+
if (this.instance && Object.keys(this._optionToUpdate).length) {
117+
this.instance.option(this._optionToUpdate);
118+
this._optionToUpdate = {};
119+
}
120+
}
122121
ngAfterViewInit() {
123122
if (this.renderOnViewInit) {
124123
this._createWidget(this.element.nativeElement);

templates/component.tst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,13 @@ export class <#= it.className #>Component extends <#= baseClass #> <#? implement
148148
this._watcherHelper.checkWatchers();
149149
}
150150

151-
_updateOption(name: string, value: any) {
151+
_setOption(name: string, value: any) {
152152
if (Array.isArray(value)) {
153153
this._idh.setupSingle(name, value);
154154
this._idh.getChanges(name, value);
155155
}
156156

157-
super._updateOption(name, value);
157+
super._setOption(name, value);
158158
}<#?#>
159159
<#? it.isEditor #>
160160
ngAfterContentInit() {

tests/src/core/component.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ describe('DevExtreme Angular widget', () => {
229229
instance = getWidget(fixture);
230230

231231
testComponent.testOption = 'Changed 2';
232+
fixture.detectChanges();
232233
expect(instance.option('testOption')).toBe('Changed 2');
233234

234235
}));

tests/src/ui/tab-panel.spec.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/* tslint:disable:component-selector */
2+
3+
import {
4+
Component,
5+
ViewChild
6+
} from '@angular/core';
7+
8+
import {
9+
TestBed,
10+
async
11+
} from '@angular/core/testing';
12+
13+
import {
14+
DxTabPanelModule,
15+
DxTabPanelComponent
16+
} from '../../../dist';
17+
18+
@Component({
19+
selector: 'test-container-component',
20+
template: `
21+
<dx-tab-panel
22+
[dataSource]="tabPanelItems"
23+
[selectedIndex]="selectedIndex">
24+
</dx-tab-panel>
25+
`
26+
})
27+
class TestContainerComponent {
28+
@ViewChild(DxTabPanelComponent) tabPanel: DxTabPanelComponent;
29+
30+
tabPanelItems: number[] = [0];
31+
selectedIndex = 0;
32+
}
33+
34+
describe('DxTagBox', () => {
35+
36+
beforeEach(() => {
37+
TestBed.configureTestingModule(
38+
{
39+
declarations: [TestContainerComponent],
40+
imports: [DxTabPanelModule]
41+
});
42+
});
43+
44+
// spec
45+
it('option, dependenced on dataSource, slould be applyed', async(() => {
46+
let fixture = TestBed.createComponent(TestContainerComponent);
47+
fixture.detectChanges();
48+
49+
let component: any = fixture.componentInstance;
50+
component.tabPanelItems.push(1);
51+
component.selectedIndex = 1;
52+
fixture.detectChanges();
53+
54+
let instance: any = component.tabPanel.instance;
55+
expect(instance.option('items').length).toBe(2);
56+
expect(instance.option('selectedIndex')).toBe(1);
57+
}));
58+
});

0 commit comments

Comments
 (0)