Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use renderer2 to manipulate elements #687

Merged
merged 6 commits into from
Feb 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## Unreleased

### Breaking changes
Angular version 2.x is no longer supported. Now our integration library is based on the Angular Renderer2 class, which is available starting with Angular version 4 and allows manipulating DOM elements on the server side (server-side rendering).

## 17.2.5-beta.1 (2017-12-26)

### Bug Fixes
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
"license": "MIT",
"peerDependencies": {
"devextreme": "~17.2.4",
"@angular/core": ">2.4.2",
"@angular/common": ">2.4.2",
"@angular/forms": ">2.4.2"
"@angular/core": ">4.0.0",
"@angular/common": ">4.0.0",
"@angular/forms": ">4.0.0"
},
"devDependencies": {
"devextreme": "~17.2.4",
Expand Down
3 changes: 0 additions & 3 deletions shippable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,3 @@ build:
- shippable_retry npm install @angular/core@^5.0.0-rc.1 @angular/common@^5.0.0-rc.1 @angular/forms@^5.0.0-rc.1 @angular/compiler@^5.0.0-rc.1 @angular/platform-browser@^5.0.0-rc.1 @angular/platform-browser-dynamic@^5.0.0-rc.1 --unsafe-perm
- gulp build.tests
- gulp run.tests
- shippable_retry npm install @angular/core@^2.4.2 @angular/common@^2.4.2 @angular/forms@^2.4.2 @angular/compiler@^2.4.2 @angular/platform-browser@^2.4.2 @angular/platform-browser-dynamic@^2.4.2 --unsafe-perm
- gulp build.tests
- gulp run.tests
5 changes: 3 additions & 2 deletions src/core/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ import {
AfterViewInit
} from '@angular/core';

import { ɵgetDOM as getDOM } from '@angular/platform-browser';

import { DxTemplateDirective } from './template';
import { IDxTemplateHost, DxTemplateHost } from './template-host';
import { EmitterHelper } from './events-strategy';
import { WatcherHelper } from './watcher-helper';
import * as events from 'devextreme/events';
import { removeElement } from './utils';
import {
INestedOptionContainer,
ICollectionNestedOption,
Expand Down Expand Up @@ -123,7 +124,7 @@ export abstract class DxComponent implements OnChanges, OnInit, DoCheck, AfterCo
let element = this.instance.element();
events.triggerHandler(element, { type: 'dxremove', _angularIntegration: true });
this.instance.dispose();
removeElement(element);
getDOM().remove(element);
}
}
constructor(protected element: ElementRef, private ngZone: NgZone, templateHost: DxTemplateHost, private watcherHelper: WatcherHelper) {
Expand Down
13 changes: 7 additions & 6 deletions src/core/nested-option.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { QueryList, ElementRef } from '@angular/core';
import { QueryList, ElementRef, Renderer2 } from '@angular/core';
import { ɵgetDOM as getDOM } from '@angular/platform-browser';

import { DX_TEMPLATE_WRAPPER_CLASS } from './template';
import { addClass, hasClass, getElement } from './utils';
import { getElement } from './utils';

import * as events from 'devextreme/events';

Expand Down Expand Up @@ -131,7 +132,7 @@ export interface IOptionWithTemplate extends BaseNestedOption {
let triggerShownEvent = function(element) {
let changeHandlers = [];

if (hasClass(element, VISIBILITY_CHANGE_SELECTOR)) {
if (getDOM().hasClass(element, VISIBILITY_CHANGE_SELECTOR)) {
changeHandlers.push(element);
}

Expand All @@ -142,7 +143,7 @@ let triggerShownEvent = function(element) {
}
};

export function extractTemplate(option: IOptionWithTemplate, element: ElementRef) {
export function extractTemplate(option: IOptionWithTemplate, element: ElementRef, renderer: Renderer2, document: any) {
if (!option.template === undefined || !element.nativeElement.hasChildNodes()) {
return;
}
Expand All @@ -164,13 +165,13 @@ export function extractTemplate(option: IOptionWithTemplate, element: ElementRef
render: (renderData) => {
let result = element.nativeElement;

addClass(result, DX_TEMPLATE_WRAPPER_CLASS);
renderer.addClass(result, DX_TEMPLATE_WRAPPER_CLASS);

if (renderData.container) {
let container = getElement(renderData.container);
let resultInContainer = container.contains(element.nativeElement);

container.appendChild(element.nativeElement);
renderer.appendChild(container, element.nativeElement);

if (!resultInContainer) {
let resultInBody = document.body.contains(container);
Expand Down
10 changes: 7 additions & 3 deletions src/core/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import {
TemplateRef,
ViewContainerRef,
Input,
Renderer2,
NgZone
} from '@angular/core';

import { DxTemplateHost } from './template-host';
import { addClass, getElement } from './utils';
import { getElement } from './utils';
import * as events from 'devextreme/events';

export const DX_TEMPLATE_WRAPPER_CLASS = 'dx-template-wrapper';
Expand All @@ -34,6 +35,7 @@ export class DxTemplateDirective {
constructor(private templateRef: TemplateRef<any>,
private viewContainerRef: ViewContainerRef,
templateHost: DxTemplateHost,
private renderer: Renderer2,
private ngZone: NgZone) {
templateHost.setTemplate(this);
}
Expand All @@ -46,7 +48,7 @@ export class DxTemplateDirective {
let container = getElement(renderData.container);
if (renderData.container) {
childView.rootNodes.forEach((element) => {
container.appendChild(element);
this.renderer.appendChild(container, element);
});
}
// =========== WORKAROUND =============
Expand All @@ -56,7 +58,9 @@ export class DxTemplateDirective {
});
// =========== /WORKAROUND =============
childView.rootNodes.forEach((element) => {
addClass(element, DX_TEMPLATE_WRAPPER_CLASS);
if (element.nodeType === 1) {
this.renderer.addClass(element, DX_TEMPLATE_WRAPPER_CLASS);
}

events.one(element, 'dxremove', (e) => {
if (!e._angularIntegration) {
Expand Down
31 changes: 0 additions & 31 deletions src/core/utils.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,3 @@
export function addClass(element: any, name: string) {
if (element.nodeType === 1) {
if (element.classList) {
element.classList.add(name);
} else {
element.className = element.className ? element.className + ' ' + name : name;
}

}
};

export function hasClass(element: any, name: string) {
let result;

if (element.classList) {
result = element.classList.contains(name);
} else {
result = element.className.split(' ').indexOf(name) >= 0;
}

return result;
};

export function getElement(element: any) {
return element.get ? element.get(0) : element;
};

export function removeElement(element: any) {
let node = getElement(element),
parentNode = node && node.parentNode;
if (parentNode) {
parentNode.removeChild(node);
}
};
8 changes: 7 additions & 1 deletion templates/nested-component.tst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
NgModule,
Host,<#? it.hasTemplate #>
ElementRef,
Renderer2,
Inject,
AfterViewInit,<#?#>
SkipSelf<#? it.properties #>,
Input<#?#><#? it.collectionNestedComponents.length #>,
Expand All @@ -13,6 +15,8 @@ import {
QueryList<#?#>
} from '@angular/core';

<#? it.hasTemplate #>import { DOCUMENT } from '@angular/common';<#?#>

<#? it.isDevExpressRequired #>
import DevExpress from 'devextreme/bundles/dx.all';<#?#>

Expand Down Expand Up @@ -56,6 +60,8 @@ export class <#= it.className #>Component extends <#= it.baseClass #><#? it.hasT
<#~#>
constructor(@SkipSelf() @Host() parentOptionHost: NestedOptionHost,
@Host() optionHost: NestedOptionHost<#? it.hasTemplate #>,
private renderer: Renderer2,
@Inject(DOCUMENT) private document: any,
@Host() templateHost: DxTemplateHost,
private element: ElementRef<#?#>) {
super();
Expand All @@ -74,7 +80,7 @@ export class <#= it.className #>Component extends <#= it.baseClass #><#? it.hasT
this.template = template;
}
ngAfterViewInit() {
extractTemplate(this, this.element);
extractTemplate(this, this.element, this.renderer, this.document);
}
<#?#>
}
Expand Down
12 changes: 10 additions & 2 deletions tests/src/core/nested-option.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
ViewChildren,
NgZone,
Input,
Renderer2,
Inject,
Output,
ContentChildren,
QueryList,
Expand All @@ -15,6 +17,8 @@ import {
AfterViewInit
} from '@angular/core';

import { DOCUMENT } from '@angular/common';

import {
TestBed,
async
Expand Down Expand Up @@ -116,7 +120,11 @@ export class DxiTestCollectionOptionWithTemplateComponent extends CollectionNest

shownEventFired = false;

constructor(@SkipSelf() @Host() private _pnoh: NestedOptionHost, @Host() private _noh: NestedOptionHost, private element: ElementRef) {
constructor(@SkipSelf() @Host() private _pnoh: NestedOptionHost,
@Host() private _noh: NestedOptionHost,
private element: ElementRef,
private renderer: Renderer2,
@Inject(DOCUMENT) private document: any) {
super();

this._pnoh.setNestedOption(this);
Expand All @@ -126,7 +134,7 @@ export class DxiTestCollectionOptionWithTemplateComponent extends CollectionNest
ngAfterViewInit() {
let element = this.element.nativeElement;

extractTemplate(this, this.element);
extractTemplate(this, this.element, this.renderer, this.document);

element.classList.add('dx-visibility-change-handler');
events.on(element, 'dxshown', function() {
Expand Down