我正在制作一个数据表组件。为了实现可访问性,我希望每个表头都通过title属性提供工具提示。可以显式设置工具提示值(以防它与标题中的文本不同),但是默认情况下,我希望它使用内部文本中的任何内容。

我有一个半工作的解决方案,但它不是很有效,我不知道是否通过这种方式违反了一些Angular规则。

这是我的缩写html:

<div #headerContent [attr.title]="title"><ng-content></ng-content></div>


我正在用headerContent标记div,以便以后参考。

好的,现在是缩写的组件类:

@Component({ ... })
export class TableHeaderComponent implements AfterContentInit {
    @ViewChild('headerContent') headerContent: ElementRef;
    @Input() title: string;

    ngAfterContentInit() {
        if (!this.title) {
            this.title = this.headerContent.nativeElement.textContent.trim();
        }
    }
}


这个想法是,如果未指定title,请查看div并获取其文本内容,并将其用作title

当我在浏览器中对其进行测试时,这可以正常工作。

用法示例:

<th table-header>Contact</th>


在这里,由于我未指定title,因此应使用Contact作为title

但是,当我为此组件编写单元测试时,它会爆炸:

Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'undefined'. Current value: 'Contact'


我不确定我在做什么错。

编辑:将ChangeDetectorRef注入我的组件类并在更新detectChanges()属性后调用title似乎已经解决了问题。它可以在浏览器中工作,并且单元测试也可以通过。

仍然想知道这样做是否违反了Angular中的任何规则。

最佳答案

我可以通过在更新属性后手动触发更改检测来解决此问题。

为此,首先将ChangeDetectorRef注入构造函数中:

constructor(private cd: ChangeDetectorRef) { }


然后,在更新属性后,调用cd.detectChanges()

09-25 17:08
查看更多