Skip to content

Commit 6ef57e7

Browse files
Fire shownEvent in template.render method of nested options after visibility changing
1 parent 5bbbbb8 commit 6ef57e7

File tree

2 files changed

+114
-5
lines changed

2 files changed

+114
-5
lines changed

src/core/nested-option.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ let $ = require('jquery');
55

66
import { DX_TEMPLATE_WRAPPER_CLASS } from './template';
77

8+
let VISIBILITY_CHANGE_SELECTOR = '.dx-visibility-change-handler';
9+
810
export interface INestedOptionContainer {
911
instance: any;
1012
}
@@ -142,13 +144,35 @@ export function extractTemplate(option: OptionWithTemplate, element: ElementRef)
142144
return;
143145
}
144146

147+
function triggerShownEvent($element) {
148+
let changeHandlers = $element.filter(VISIBILITY_CHANGE_SELECTOR).
149+
add($element.find(VISIBILITY_CHANGE_SELECTOR));
150+
151+
for (let i = 0; i < changeHandlers.length; i++) {
152+
$(changeHandlers[i]).triggerHandler('dxshown');
153+
}
154+
}
155+
145156
option.template = {
146157
render: (renderData) => {
158+
let $result = $(element.nativeElement)
159+
.addClass(DX_TEMPLATE_WRAPPER_CLASS);
160+
147161
if (renderData.container) {
162+
let resultInContainer = renderData.container.get(0).contains($result.get(0));
163+
148164
renderData.container.append(element.nativeElement);
165+
166+
if (!resultInContainer) {
167+
let resultInBody = document.body.contains(renderData.container.get(0));
168+
169+
if (resultInBody) {
170+
triggerShownEvent($result);
171+
}
172+
}
149173
}
150-
return $(element.nativeElement)
151-
.addClass(DX_TEMPLATE_WRAPPER_CLASS);
174+
175+
return $result;
152176
}
153177
};
154178
}

tests/src/core/nested-option.spec.ts

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,12 @@ import {
2929
import {
3030
NestedOption,
3131
CollectionNestedOption,
32-
NestedOptionHost
32+
NestedOptionHost,
33+
extractTemplate
3334
} from '../../../dist/core/nested-option';
3435

36+
let $ = require('jquery');
37+
3538
// TODO: Try to replace dxButton to Widget ('require' required)
3639
import DxButton from 'devextreme/ui/button';
3740
let DxTestWidget = DxButton['inherit']({
@@ -94,6 +97,46 @@ export class DxiTestCollectionOptionComponent extends CollectionNestedOption {
9497
}
9598
}
9699

100+
@Component({
101+
selector: 'dxi-test-collection-option-with-template',
102+
template: '<ng-content></ng-content>',
103+
providers: [NestedOptionHost]
104+
})
105+
export class DxiTestCollectionOptionWithTemplateComponent extends CollectionNestedOption implements AfterViewInit {
106+
protected get _optionPath() {
107+
return 'testCollectionWithTemplateOption';
108+
}
109+
110+
get template() {
111+
return this._getOption('template');
112+
}
113+
set template(value: any) {
114+
this._setOption('template', value);
115+
}
116+
117+
shownEventFired = false;
118+
119+
constructor(@SkipSelf() @Host() private _pnoh: NestedOptionHost, @Host() private _noh: NestedOptionHost, private element: ElementRef) {
120+
super();
121+
122+
this._pnoh.setNestedOption(this);
123+
this._noh.setHost(this, this._fullOptionPath.bind(this));
124+
}
125+
126+
ngAfterViewInit() {
127+
let $element = $(this.element.nativeElement);
128+
129+
extractTemplate(this, this.element);
130+
131+
$element.addClass('dx-visibility-change-handler');
132+
$element.on('dxshown', function() {
133+
this.shownEventFired = true;
134+
}.bind(this));
135+
136+
this.template.render({ container: $('dx-test-widget') });
137+
}
138+
}
139+
97140
@Component({
98141
selector: 'dx-test-widget',
99142
template: '',
@@ -114,6 +157,13 @@ export class DxTestWidgetComponent extends DxComponent implements AfterViewInit
114157
set testCollectionOption(value: any) {
115158
this._setOption('testCollectionOption', value);
116159
};
160+
@Input()
161+
get testCollectionOptionWithTemplate(): any {
162+
return this._getOption('testCollectionOptionWithTemplate');
163+
}
164+
set testCollectionOptionWithTemplate(value: any) {
165+
this._setOption('testCollectionOptionWithTemplate', value);
166+
};
117167

118168
@ContentChildren(DxiTestCollectionOptionComponent)
119169
get testCollectionOptionChildren(): QueryList<DxiTestCollectionOptionComponent> {
@@ -123,9 +173,21 @@ export class DxTestWidgetComponent extends DxComponent implements AfterViewInit
123173
this.setChildren('testCollectionOption', value);
124174
}
125175

176+
@ContentChildren(DxiTestCollectionOptionWithTemplateComponent)
177+
get testCollectionOptionWithTemplateChildren(): QueryList<DxiTestCollectionOptionWithTemplateComponent> {
178+
return this._getOption('testCollectionOptionWithTemplate');
179+
}
180+
set testCollectionOptionWithTemplateChildren(value) {
181+
this.setChildren('testCollectionOptionWithTemplate', value);
182+
}
183+
184+
@ContentChildren(DxiTestCollectionOptionWithTemplateComponent)
185+
testCollectionOptionWithTemplateChildrens: QueryList<DxiTestCollectionOptionWithTemplateComponent>;
186+
126187
@Output() onOptionChanged = new EventEmitter<any>();
127188
@Output() testOptionChange = new EventEmitter<any>();
128189
@Output() testCollectionOptionChange = new EventEmitter<any>();
190+
@Output() testCollectionOptionWithTemplateChange = new EventEmitter<any>();
129191

130192
constructor(elementRef: ElementRef, ngZone: NgZone, templateHost: DxTemplateHost, private _noh: NestedOptionHost,
131193
_watcherHelper: WatcherHelper) {
@@ -134,7 +196,8 @@ export class DxTestWidgetComponent extends DxComponent implements AfterViewInit
134196
this._events = [
135197
{ subscribe: 'optionChanged', emit: 'onOptionChanged' },
136198
{ emit: 'testOptionChange' },
137-
{ emit: 'testCollectionOptionChange' }
199+
{ emit: 'testCollectionOptionChange' },
200+
{ emit: 'testCollectionOptionWithTemplate' }
138201
];
139202

140203
this._noh.setHost(this);
@@ -168,7 +231,8 @@ describe('DevExtreme Angular widget', () => {
168231
TestContainerComponent,
169232
DxTestWidgetComponent,
170233
DxoTestOptionComponent,
171-
DxiTestCollectionOptionComponent
234+
DxiTestCollectionOptionComponent,
235+
DxiTestCollectionOptionWithTemplateComponent
172236
]
173237
});
174238
});
@@ -238,4 +302,25 @@ describe('DevExtreme Angular widget', () => {
238302
expect(instance.option('testCollectionOption')[0].testOption).toEqual({ testNestedOption: 'text' });
239303
}));
240304

305+
it('method template.render of nested option should trigger shownEvent after rendering', async(() => {
306+
TestBed.overrideComponent(TestContainerComponent, {
307+
set: {
308+
template: `
309+
<dx-test-widget>
310+
<dxi-test-collection-option-with-template>
311+
<div>123</div>
312+
</dxi-test-collection-option-with-template>
313+
</dx-test-widget>
314+
`
315+
}
316+
});
317+
let fixture = TestBed.createComponent(TestContainerComponent);
318+
fixture.detectChanges();
319+
320+
let innerWidget = fixture.componentInstance.innerWidgets.first;
321+
let nestedOption = innerWidget.testCollectionOptionWithTemplateChildrens.first;
322+
323+
expect(nestedOption.shownEventFired).toBe(true);
324+
}));
325+
241326
});

0 commit comments

Comments
 (0)