如何根据子内容更新组件的属性?

时间:2017-08-07 19:33:47

标签: javascript angular

我正在制作一个数据表组件。对于辅助功能,我希望每个表标题都通过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中的任何规则来这样做。

1 个答案:

答案 0 :(得分:1)

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

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

constructor(private cd: ChangeDetectorRef) { }

然后在更新属性后,请致电cd.detectChanges()