2017-08-07 80 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()