In Angular 1 all DOM manipulation should be done in directives to ensure proper testability, but what about Angular 2? How has this changed?
I've been searching for good articles or any information at all about where to put DOM manipulation and how to think when doing it, but I come up empty every time.
Take this component for example (this is really a directive but let's pretend that it's not):
export class MyComponent {
constructor(private _elementRef: ElementRef) {
this.setHeight();
window.addEventListener('resize', (e) => {
this.setHeight();
});
}
setHeight() {
this._elementRef.nativeElement.style.height = this.getHeight() + 'px';
}
getHeight() {
return window.innerHeight;
}
}
Does event binding belong in a constructor for example, or should this be put in the ngAfterViewInit
function or somewhere else? Should you try to break out the DOM manipulation of a component into a directive?
It's all just a blur at the moment so I'm not sure that I'm going about it correctly and I'm sure I'm not the only one.
What are the rules for DOM manipulation in Angular2?
EVENT BINDING : The flow of information from elements in a component to the corresponding component's class is event binding (HTML Template to TS) . Event binding works without having to define a template reference variable. This is the best and the easiest method to manipulate DOM elements.
Where should we implement the DOM manipulation in AngularJS? In the directives. DOM Manipulations should not exist in controllers, services or anywhere else but in directives.
We can access the DOM in Angular using different reference types like ElementRef , TemplateRef , ViewRef , ComponentRef and ViewContainerRef . These reference types can be queried from templates using @ViewChild and @ContentChild . Browser's native DOM element can be accessed via ElementRef .
Based upon recommend solution by developers: http://angularjs.blogspot.de/2016/04/5-rookie-mistakes-to-avoid-with-angular.html
@Component({
selector: 'my-comp',
template: `
<div #myContainer>
</div>
`
})
export class MyComp implements AfterViewInit {
@ViewChild('myContainer') container: ElementRef;
constructor() {}
ngAfterViewInit() {
var container = this.container.nativeElement;
console.log(container.width); // or whatever
}
}
Attention: The view child name has to begin with myName and in the template you need #.
Direct DOM manipulation should be avoided entirely in Angular2.
Use instead bindings like:
export class MyComponent {
constructor() {
this.setHeight();
}
@HostBinding('style.height.px')
height:number;
@HostListener('window:resize', ['$event'])
setHeight() {
this.height = window.innerHeight;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With