2017-08-07 16 views
0

私はデータテーブルコンポーネントを作成しています。アクセシビリティのために、各テーブルヘッダーにtitle属性を使用してツールチップを付ける必要があります。ツールヒントの値は明示的に設定することができます(ヘッダーのテキストと異なる場合)。しかし、デフォルトでは、内部テキストが何であれ使用する必要があります。子コンテンツに基づいてコンポーネントのプロパティを更新するにはどうすればよいですか?

私はハーフワーキングのソリューションを持っていますが、これはうまく機能しません。この方法でいくつかの角度ルールを破っているかどうかわかりません。私は、私は後でそれを参照することができますheaderContentでのdivタグ付けしています

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

は、ここに私の省略コンポーネントのhtmlです。

@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のためにそれを使用して、そのテキストの内容をつかむことです:

OK]をクリックして、今ここに簡略コンポーネントクラスです。

これはブラウザでテストするとうまく動作します。

使用例:ここでは

<th table-header>Contact</th> 

、私はtitleを指定していなかったので、それはtitleとしてContact使用する必要があります。

しかし、私はこのコンポーネントのユニットテストを書くとき、それはと吹く:私はここで間違ってやっているかわからないんだけど

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

EDIT:ChangeDetectorRefをコンポーネントクラスに注入し、プロパティを更新した後に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()を呼び出します。

関連する問題