0

I'm currently trying to give classes to an wrapper that contains all of my app, i usually find this handy for giving certain states like when the header is fixed, or the menu's are opened etc.

So upon reading through some the docs of angular i should probably use an 'Directive'. Now i got this all set up and it looks like this:

constructor(private router:Router, @Inject(DOCUMENT) private document:Document, el:ElementRef, renderer:Renderer) {
    this.setClasses(el, renderer);
}

setClasses(el:ElementRef, renderer:Renderer) {
    renderer.setElementClass(el.nativeElement, 'header-fixed', this.headerFixed);
}

@HostListener("window:scroll", [])onWindowScroll() {
    let number = this.document.body.scrollTop;

    if (number > 100) {
        this.headerFixed = true;
    } else if (this.headerFixed && number < 10) {
        this.headerFixed = false;
    }
}

Now this is working perfectly but as you can see i'm toggling the headerFixed variable depending on scroll position. However i could of course run the function setClasses() again and it will work but is there anyway to subscribe/watch the variable and update automatically when changed?

Or is there even a better way of achieving wat i'm trying to do?

LVDM
  • 444
  • 2
  • 23
  • 1
    Have you tried to use `@HostBinding('header-fixed')` together with getter? http://stackoverflow.com/questions/35168683/hostbinding-with-a-variable-class-in-angular2 – yurzui Dec 05 '16 at 14:31
  • Ah yeah that works thanks! – LVDM Dec 05 '16 at 14:53
  • 1 more thing, it's sort of related, for example within the directive selector i have an button that toggles menuOpen like: `(click)="menuOpen = !menuOpen"` in the directive the variable is declared like: `@HostBinding('class.menu-open') menuOpen = false;` but it doesn't work. Any idea hoe to best handle those kind of events? – LVDM Dec 05 '16 at 14:56
  • What about using getter? – yurzui Dec 05 '16 at 14:58
  • Could you post an example link? Would be appreciated, also if you post an answer i'll accept it. – LVDM Dec 05 '16 at 15:00
  • Can you show me example of html with `click` event? – yurzui Dec 05 '16 at 15:01
  • `` it's within the directive's selector but has it's in another component. (header.component) – LVDM Dec 05 '16 at 15:02
  • Does your directive has input property [menuOpen]="menuOpen"? – yurzui Dec 05 '16 at 15:04
  • wrapper-class.directive.ts has `@HostBinding('class.menu-open') menuOpen = false;` header.component.ts is empty only assigning the template and styles in here. – LVDM Dec 05 '16 at 15:07
  • Take this as example https://plnkr.co/edit/GL0Qdb4N9z3Z8Itaq0Ta?p=preview – yurzui Dec 05 '16 at 15:08
  • Thanks for the example, seems to do everything i want, only for some reason i get an type error when i try to to compile this locally. `wrapper-class.directive.ts:12:44 '(' expected. ` it's becasue of the `get redClass { ... }` – LVDM Dec 05 '16 at 15:26
  • i think the example you gave me is not working because my structure is a bit different, my app.component is loading header.component and within the header.component template the button is located. Doesn't mater if i define `menuOpen` there, i'm still getting some errors. – LVDM Dec 05 '16 at 16:37
  • Can you reproduce it on the plunker? – yurzui Dec 05 '16 at 16:38
  • Of course: https://plnkr.co/edit/leWupEhc0MsSrX0VjcvF?p=preview – LVDM Dec 05 '16 at 16:58
  • I don't see where you use `MyDirective` – yurzui Dec 05 '16 at 16:59
  • My badd updated it, it wraps the header https://plnkr.co/edit/48sxN2WIjuhRcoZN5T3S?p=preview – LVDM Dec 05 '16 at 17:03
  • See my plunker within answer – yurzui Dec 05 '16 at 17:44

1 Answers1

2

You can use @HostBinding like:

@HostBinding('class.header-fixed') get myClass() { 
  return someCondition; 
}

Plunker Example

yurzui
  • 205,937
  • 32
  • 433
  • 399