Reputation: 907
I am using Angular 5. What I am trying to do is a responsive side navigation bar. When the window width changes I need some events to apply (css, content etc). In my example I want to change the inner Html - text, when the window width is below of 1080 pixels.
I tried three ways. By javascript and ng-model but nothing.
Html:
<div id="nav-left">
<mat-list>
<mat-list-item><a id="elp1" [routerLink]="['/']" fragment="intro-text" ng-model="innerHtml"> Welcome </a></mat-list-item>
<mat-list-item><a id="elp2" [routerLink]="['/']" fragment="introduction"> Introduction </a></mat-list-item>
...
</mat-list>
</div>
Component (first way):
@HostListener('window:resize', ['$event'])
onResize(event?) {
this.screenWidth = window.innerWidth;
let bgScreen = true;
let smScreen = true;
if(this.screenWidth < 1080 && smScreen){
document.getElementById("elp1").innerHTML = "New";
smScreen = false;
bgScreen = true;
}else if(this.screenWidth >= 1080 && bgScreen){
document.getElementById("elp1").innerHTML = " Welcome ";
bgScreen = false;
smScreen = true;
}else{
console.log('problem');
}
}
In this case I get a console error:
Uncaught (in promise): TypeError: Cannot set property 'innerHTML' of null
Component (second way):
@HostListener('window:resize', ['$event'])
onResize(event?) {
this.screenWidth = window.innerWidth;
if(this.screenWidth < 1080){
let element = <HTMLInputElement>document.getElementById("elp1");
element.value = "New";
}else if(this.screenWidth >= 1080){
let element = <HTMLInputElement>document.getElementById("elp1");
element.value = "Welcome";
}else{
console.log('problem');
}
}
With the error:
Uncaught (in promise): TypeError: Cannot set property 'value' of null
Component (third way & ng-model):
@HostListener('window:resize', ['$event'])
onResize(event?) {
this.screenWidth = window.innerWidth;
if(this.screenWidth < 1080){
let innerHtml :string = "New";
}else if(this.screenWidth >= 1080){
let innerHtml :string = "Welcome";
}else{
console.log('problem');
}
}
With no errors but it doesn't work.
1) The first problem are the above errors. 2) and secondly as you see in the "first way" example I tried to add flags trigger effects and realized that didn't worked either. Variables "bgScreen" and "smScreen" are always true. I put those for a better coding flow.
I don't want to use jQuery. Only typescript or with angular (ng-model) way. Any suggestions?
Upvotes: 1
Views: 3399
Reputation: 73721
I recommend using data binding to set the content of the link:
<div id="nav-left">
<mat-list>
<mat-list-item><a [routerLink]="['/']" fragment="intro-text"> {{introText}} </a></mat-list-item>
...
</mat-list>
</div>
The public property introText
can be modified when the window is resized:
introText = "Welcome";
@HostListener("window:resize", ["$event"])
onResize(event) {
this.introText = window.innerWidth < 1080 ? "New" : "Welcome";
}
or, as an alternative, you could define introText
as a getter (not handling the resize
event):
get introText(): string {
return window.innerWidth < 1080 ? "New" : "Welcome";
}
Upvotes: 1
Reputation: 435
To get element instead of using document.getElementById("elp1")
try ViewChild
of angular if child element of component, or ElementRef
for component itself. As here it looks child element of Component you could use ViewChild
You will get the access to element in angular component.
so now your HTML would be
<mat-list-item><a #elp1 [routerLink]="['/']" fragment="intro-text"> Welcome </a></mat-list-item>
and in @component
import { ViewChild} from '@angular/core';
.
.
@ViewChild('elp1') link;
//And assign values like below now.
this.link.nativeElement.innerHTML = "New";
Hope this helps.
Upvotes: 0