带标题的省略号指令

时间:2019-03-11 15:57:23

标签: angular angular-directive

我有一个Angular指令,该指令在text-overflow: ellipsis; overflow: hidden; white-space: nowrap;中添加样式ngOnInit,然后看起来像这样:

@Directive({ selector: 'ellipsis' })
class EllipsisDirective {
  ngAfterViewInit() {
    const el: HTMLElement = this.el.nativeElement;
    if (el.offsetWidth < el.scrollWidth) {
      el.setAttribute('title', el.innerText);
    }
  }
}

用法:<div ellipsis>Some Very Long Text Here</div>

问题:
在某些页面上,布局/组件不会在“导航”上更改,只有数据会更改。当前,该伪指令不会占用el.innerText中的差异,因此保留了旧的.title属性。

我还尝试使用Input()并与ngOnChanges()一起使用。我宁愿不使用输入。

我可以使其与输入和setTimeout一起使用,但这绝不是可行的方法。

1 个答案:

答案 0 :(得分:0)

我想应该从official docs开始。答案是使用AfterViewChecked生命周期事件。

  

AfterViewChecked
  Angular检查投影到指令/组件中的内容后响应。

     

在ngAfterContentInit()和随后的每个ngDoCheck()之后调用。

@Directive({ selector: '[appEllipsis]' })
export class EllipsisDirective implements OnInit, AfterViewChecked {
  private get hasOverflow(): boolean {
    const el: HTMLElement = this.el.nativeElement;
    return el.offsetWidth < el.scrollWidth;
  }

  constructor(
    private el: ElementRef,
    @Inject(PLATFORM_ID) private platformId: any,
  ) {}

  ngOnInit() {
    // class overflow: text-overflow: ellipsis; overflow: hidden; white-space: nowrap;
    this.el.nativeElement.classList.add('overflow');
  }

  ngAfterViewChecked() {
    const isBrowser = isPlatformBrowser(this.platformId);
    if (isBrowser) {
      if (this.hasOverflow) {
        this.el.nativeElement.setAttribute('title', this.el.nativeElement.innerText);
      } else {
        this.el.nativeElement.setAttribute('title', '');
      }
    }
  }
}