2017-08-07 46 views
0

我正在制作一个数据表组件。对于可访问性,我希望每个表头都有一个通过title属性的工具提示。工具提示值可以被明确地设置(如果它不同于标题中的文本),但是默认情况下,我希望它使用任何内部文本。如何根据子内容更新组件的属性?

我有一个半工作的解决方案,但它不是很工作,我不知道是否通过这样做打破了一些Angular规则。

这里是我的缩写组成的html:

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

我标记与headerContent股利,所以我可以在以后引用它。

好了,现在这里的缩写组件类:

@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,它应该使用Contacttitle

但是,当我写单元测试这个组件,它吹了:

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

我不知道我在做什么错在这里。

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

仍然想知道这是否违反Angular的任何规则来做到这一点。

+1

这应该在'ngOnInit'中完成,你可以在这个问题中获得更多信息(https://stackoverflow.com/questions/43375532/expressionchangedafterithasbeencheckederror-explained)至于为什么:) – 0mpurdy

+0

但是在'ngOnInit ','@ ViewChild'不会被初始化吗? 'ngAfterViewInit'不会发生这种情况吗?我只是试过这个,在'ngOnInit()''this.headerContent'是'undefined'。 –

+1

我必须承认我尽可能避免使用'@ ViewChild',我通常会试着找到完成任务的另一种方式,现在我会试着创建一个蹲下来测试这个问题:) – 0mpurdy

回答

1

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

要做到这一点,首先注入在构造函数中ChangeDetectorRef

constructor(private cd: ChangeDetectorRef) { } 

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