问题
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