提问者:小点点

自定义Angular指令不能使用异步值


我们的项目中有一个定制指令,当我们想要修剪一些UI元素中的长文本时,我们会使用它。 有一次它失败了。 没有错误,没有警告,只是没有。 检查DevTools中的代码没有显示触发该指令的迹象(没有HTML更改,没有添加CSS)。 指令如下所示:

ngAfterViewInit() {
  let text = <string>this.elt.nativeElement.innerHTML.trim();
  if (!text || text !== (<HTMLElement>this.elt.nativeElement).innerText) {
    return;
  }

  const limit = this.value || DEFAULT_VISIBLE_ENDING_LENGTH; // default length = 4
  if (text.length > limit && this.elt.nativeElement.scrollWidth > this.elt.nativeElement.clientWidth) {
    const startText = text.substr(0, text.length - limit);
    const endText = text.substr(-limit);
    this.renderer.setProperty(
      this.elt.nativeElement,
      'innerHTML',
      `<div class="part1"><span>${startText}</span></div><div class="part2"><span><span>${endText}</span></span></div>`
    );
  }
}

当要显示的文本&; 修剪从observable(存储选择器)获得。 不管我是使用observable+async管道,还是将值映射到选择器subscribe中的组件属性,都无关紧要。

@Component({
  ...
  changeDetection: ChangeDetectionStrategy.OnPush,
})

this.sampleInProgress$: Observable<string>;
this.sampleInProgress: string;
...
this.sampleInProgress$ = this.store.select(fromAutomation.getInfoPanelData).pipe(
  map(({ sample, experiment }) => {
    this.sampleInProgress = sample?.sampleName; // does not work either
    this.experimentInProgress = experiment?.parameterSet;
    return sample?.sampleName;
  }),
);

和HTML:

<span class="label" gs-ellipsis>{{ sampleInProgress$ | async }}</span>
<!-- In this case, subscribe is done in the component -->
<span class="label" gs-ellipsis>{{ sampleInProgress }}</span>

对不起,有点混乱的代码,我只是不想张贴几乎相同的代码两次。 我要么显式订阅,要么使用async分配可观察对象。 而不是同时做这两件事。 代码中使用省略号的另一个地方(也是省略号工作的地方)也使用onPush检测策略,但是值是由@input提供的。

我有一种感觉,它与指令本身中的NGAfterViewInit()有关,但我不确定。 指令不是我最强的领域。

知道是什么导致的吗?怎么解决?


共1个答案

匿名用户

您的指令处理发生得太早了。 我假设您可以在ngIf指令的帮助下稍微修改一下它,并在它的内容没有问题的情况下呈现元素。

<span class="label" gs-ellipsis *ngIf="sampleInProgress$ | async as value">{{ value }}</span>