Reputation: 1803
I'm using the latest Angular 2 beta (45?) and am trying to attach an ngClass to the element identified by the directive selector. The variable used to toggle the class does not update.
I suspect it's one of two things:
Is there a way to do what I'm trying to do? Is that just not how it's done anymore?
Sample code written from memory since I do not have access to it presently:
@Directive({
selector: "nav",
templateUrl: "templates/nav.html"
});
export class NavComponent {
isOpen:Boolean = false;
onScroll(e) {
this.isOpen = true;
}
window.onscroll = (e) => this.onScroll.call(this); // .call seemed necessary, because otherwise the scope of 'this' changed to window instead of the directive
}
The following does not work:
index.html
<nav [ngClass]="{open: isOpen}"></nav>
templates/nav.html
<a href="#">whatever</a>
...
<a href="#">whatever 2</a>
The following does work:
index.html
<nav></nav>
templates/nav.html
<div [ngClass]="{open: isOpen}">
<a href="#">whatever</a>
...
<a href="#">whatever 2</a>
</div>
Upvotes: 3
Views: 1578
Reputation: 364747
In addition to Günter's answer, use a host listener instead of assigning an event handler to window.onscroll
. Then Angular change detection will run and actually update the CSS class when you scroll. (Otherwise, some other event will need to happen before the view gets updated.)
@Component({
selector: "nav",
template: `<a href="#">whatever</a>
<a href="#">whatever 2</a>`,
host: {
'(window:scroll)': 'onScroll($event)', // <<------
'[class.open]': 'isOpen'
}
})
export class NavComponent {
isOpen:Boolean = false;
onScroll(e) {
this.isOpen = true;
}
}
@Component({
selector: 'my-app',
template: `<nav></nav>
<div *ngFor="#row of dummyArray; #i = index">row {{i}}</div>`,
styles: ['.open { background-color: lightblue }']
directives: [NavComponent]
})
export class AppComponent {
dummyArray = new Array(100);
constructor() { console.clear(); }
}
Upvotes: 3
Reputation: 658067
isOpen
in
<nav [ngClass]="{open: isOpen}"></nav>
refers to the parent component of <nav>
, the component that has <nav>
in its template.
If you want to set the class on the directives host, use
@Directive({
selector: "nav",
templateUrl: "templates/nav.html",
host: {'[class.open]': 'isOpen'}
});
export class NavComponent {
isOpen:Boolean = false;
onScroll(e) {
this.isOpen = true;
}
}
Upvotes: 1