【问题标题】:Angular 6 custom directive not updating after value changeAngular 6自定义指令在值更改后不更新
【发布时间】:2018-08-22 02:16:31
【问题描述】:

我想做一个动态菜单,菜单本身有css类,如果我选中一个复选框,菜单必须从左到右改变位置。

现在该指令有效,但只有一次,当程序加载时,如果我尝试更改程序中的复选框,则没有任何反应。

html:

<div class="wrapper">

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

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

</div>

我尝试使用(side)="position"[side]="position"[(side)]="position"

还有指令:

  @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');
        }
    }

我还在学习角度,所以出于某种原因,我不明白为什么新值似乎没有达到指令,但我不知道为什么。

我做错了什么?我错过了什么吗?

【问题讨论】:

  • 嗨,处理@Input 的正确方法是[side]=position。顺便说一句,您也可以使用@HostBinding。你能在 stackblitz 上准备一个最小的例子吗??
  • 你能给个小提琴什么的吗?

标签: angular


【解决方案1】:

您可以尝试使用行为主题。

组件:

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

指令:

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

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

    }
  }
  ngOnChanges(){

  }

【讨论】:

    【解决方案2】:

    您的代码存在一些问题。

    只需将adjustSide 用作@Input 别名,这样您就不必在指令中声明其他属性。

    像这样使用它:

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

    指令应该是这样的:

    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');
        }
      }
    
    }
    

    如果您查看控制台,您会看到 ngOnChanges 被调用。我已经通过它记录了this.side 的值。

    这里有一个StackBlitz Sample 供您使用。

    【讨论】:

    • 虽然它在您的示例中有效,但在我的角度程序中却没有。关于如何调试它的任何想法?
    • 我为您提供了示例,以便通过比较您所做的不同操作来帮助您进行调试。你能创建一个 StackBlitz 来复制你的问题吗?
    猜你喜欢
    • 2015-03-06
    • 2016-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-02
    • 1970-01-01
    • 2015-11-10
    • 2019-10-06
    相关资源
    最近更新 更多