Angular 6 custom directive not updating after value change

…衆ロ難τιáo~ 提交于 2021-02-10 18:54:25

问题


I want to make a dynamic menu, the menu itself has css class in which if i check a checkbox the menu has to change position from left to right.

Right now the directive works, but only once, when the program loads, if i try to change the check the checkbox within the program nothing happens.

the html:

<div class="wrapper">

        <div class="app-menu" adjustSide side="{{position}}">

            <router-outlet></router-outlet>
        </div>

</div>

I tried with (side)="position", [side]="position" and [(side)]="position".

And the directive:

  @Input('side') private side:string;


    private el: HTMLInputElement;

    constructor( private renderer: Renderer2, private elementRef: ElementRef ) { 
        this.el = this.elementRef.nativeElement; 
    }

     ngOnChanges(changes: { [propName: string]: SimpleChange }) {

        if (this.side == 'left') {
            this.renderer.addClass(this.el, 'offset-left');
            this.renderer.removeClass(this.el, 'offset-right');
        }else{
            this.renderer.removeClass(this.el, 'offset-left');
            this.renderer.addClass(this.el, 'offset-right');
        }
    }

I'm still learning angular, so for some reason i don't understand why it seems the new value doesn't reach to the directive, but i have no idea why.

What i'm doing wrong? did i missed something?


回答1:


You can try with Behavior Subject.

Component:

public sub = new BehaviorSubject<any>('');
this.sub.next('left');

Directive:

@Input('side') side: Observable<any>;

ngOnInit(){
    if(this.side){
      this.side.subscribe(data=>{
        console.log(data);
      });

    }
  }
  ngOnChanges(){

  }



回答2:


There are a few issues with your code.

Just use the adjustSide as an @Input alias so that you don't have to declare other properties on your directive.

Just use it like this:

<div class="wrapper">
  <div class="app-menu" [adjustSide]="position">
    <router-outlet></router-outlet>
  </div>
</div>

And the directive should be like this:

import { Directive, ElementRef, Renderer2, Input, OnChanges } from '@angular/core';

@Directive({
  selector: '[adjustSide]'
})
export class AdjustSizeDirective implements OnChanges {

  @Input('adjustSide') side: string;

  constructor(
    private el: ElementRef,
    private renderer: Renderer2
  ) { }

  ngOnChanges() {

    console.log('Side changed to : ', this.side);

    if (this.side == 'left') {
        this.renderer.addClass(this.el.nativeElement, 'offset-left');
        this.renderer.removeClass(this.el.nativeElement, 'offset-right');
    }
    else{
        this.renderer.removeClass(this.el.nativeElement, 'offset-left');
        this.renderer.addClass(this.el.nativeElement, 'offset-right');
    }
  }

}

If you have a look at the console, you'll see the ngOnChanges getting called. I've logged the value of this.side through that.

Here's a StackBlitz Sample for your case.



来源:https://stackoverflow.com/questions/51953651/angular-6-custom-directive-not-updating-after-value-change

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!