Skip to content

Commit b4bf9be

Browse files
Checking changes (#624)
1 parent c40afce commit b4bf9be

File tree

3 files changed

+56
-4
lines changed

3 files changed

+56
-4
lines changed

packages/devextreme-react/src/core/__tests__/props-updating.test.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,36 @@ describe('option control', () => {
296296
expect(Widget.option.mock.calls[0]).toEqual(['complexOption.a', 123]);
297297
});
298298

299+
it('extra option call for check changes', () => {
300+
const { rerender } = render(
301+
<ControlledComponent everyOption={123} anotherOption="const" />,
302+
);
303+
304+
Widget.option.mockImplementation((name: string) => {
305+
if (name === 'everyOption') {
306+
Widget.option('anotherOption', 'changed');
307+
return undefined;
308+
}
309+
if (name === undefined) {
310+
return {
311+
everyOption: 234,
312+
abotherOption: 'changed',
313+
};
314+
}
315+
return undefined;
316+
});
317+
318+
rerender(
319+
<ControlledComponent everyOption={234} anotherOption="const" />,
320+
);
321+
322+
jest.runAllTimers();
323+
324+
expect(Widget.option.mock.calls.length).toBe(2);
325+
expect(Widget.option.mock.calls[0]).toEqual(['everyOption', 234]);
326+
expect(Widget.option.mock.calls[1]).toEqual(['anotherOption', 'changed']);
327+
});
328+
299329
it('should not rolls back complex option if shallow equals', () => {
300330
render(
301331
<ControlledComponent complexOption={{ a: 123, b: 234 }} />,

packages/devextreme-react/src/core/__tests__/test-component.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
/* eslint-disable max-classes-per-file */
22
import { Component } from '../component';
33

4-
const eventHandlers: { [index: string]: (e?: any) => void } = {};
4+
const eventHandlers: { [index: string]: ((e?: any) => void)[] } = {};
55

66
const Widget = {
77
option: jest.fn(),
88
resetOption: jest.fn(),
99
beginUpdate: jest.fn(),
1010
endUpdate: jest.fn(),
1111
on: (event: string, handler: (e: any) => void): void => {
12-
eventHandlers[event] = handler;
12+
if (eventHandlers[event]) {
13+
eventHandlers[event].push(handler);
14+
} else {
15+
eventHandlers[event] = [handler];
16+
}
17+
},
18+
off: (event: string, handler: (e: any) => void) => {
19+
eventHandlers[event] = eventHandlers[event].filter((e) => e !== handler);
1320
},
1421
dispose: jest.fn(),
1522
};
@@ -22,6 +29,7 @@ class TestComponent<P = any> extends Component<P> {
2229
protected useDeferUpdateFlag = true;
2330

2431
_createWidget(element?: Element): void {
32+
eventHandlers.optionChanged = [];
2533
Widget.option.mockImplementation((name: string) => name === 'integrationOptions.useDeferUpdateForTemplates');
2634

2735
super._createWidget(element);
@@ -33,11 +41,11 @@ class TestPortalComponent<P = any> extends TestComponent<P> {
3341
}
3442

3543
function fireOptionChange(fullName: string, value: unknown): void {
36-
eventHandlers.optionChanged({
44+
eventHandlers.optionChanged?.forEach((e) => e({
3745
name: fullName.split('.')[0],
3846
fullName,
3947
value,
40-
});
48+
}));
4149
}
4250

4351
export {

packages/devextreme-react/src/core/options-manager.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ class OptionsManager {
6262
}
6363

6464
public update(config: IConfigNode): void {
65+
const changedOptions:Array<[string, any]> = [];
66+
const optionChangedHandler = ({ value, fullName }) => {
67+
changedOptions.push([fullName, value]);
68+
};
69+
this.instance.on('optionChanged', optionChangedHandler);
70+
6571
const changes = getChanges(config, this.currentConfig);
6672

6773
if (!changes.options && !changes.templates && !changes.removedOptions.length) {
@@ -92,6 +98,14 @@ class OptionsManager {
9298
});
9399

94100
this.isUpdating = false;
101+
this.instance.off('optionChanged', optionChangedHandler);
102+
103+
changedOptions.forEach(([name, value]) => {
104+
const currentPropValue = config.options[name];
105+
if (config.options.hasOwnProperty(name) && currentPropValue !== value) {
106+
this.setValue(name, currentPropValue);
107+
}
108+
});
95109
this.currentConfig = config;
96110
this.instance.endUpdate();
97111
}

0 commit comments

Comments
 (0)