注入页面后,组件无法访问ViewChild

时间:2017-07-03 17:45:16

标签: angular ionic3

在一个带有离子3和Angular4的全新项目中,我有一个@Component,它在画布中呈现如下内容:

分析器 - chart.html:

<div>
  <canvas #chartCanvas></canvas>
</div>

分析器 - chart.ts:

@Component({
  selector: 'analyzer-chart',
  templateUrl: 'analyzer-chart.html'
})
export class AnalyzerChartComponent {

  @ViewChild('chartCanvas') chartCanvas;

以后

new Chart(this.chartCanvas.nativeElement

此组件用于@IonicPage(AnalyzerPage)并且运行良好。

但是现在我想在analyzer.ts中调用来自AnalyzerChartComponent的方法,因此想要在页面的构造函数中注入该组件,如下所示:

@IonicPage()
@Component({
  selector: 'page-analyzer',
  templateUrl: 'analyzer.html',
  providers: [AnalyzerChartComponent]
})
export class AnalyzerPage {

  pageTitle:string = "loading...";

  constructor(public navCtrl: NavController, public navParams: NavParams,
     public analyzerChart: AnalyzerChartComponent
    ) {
  }

然后,通过将组件注入页面,它会停止工作,因为@ViewChild('chartCanvas')chartCanvas突然未定义。不知道为什么。

analyzer.html就像

<ion-content padding>

  <h1>{{ pageTitle }}</h1>
  <analyzer-selection-form></analyzer-selection-form>
  <br />
  <analyzer-chart></analyzer-chart>

</ion-content>

在包含的组件中调用成员的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

Angular在运行更改检测时更新@ViewChild('chartCanvas') chartCanvas;。在此之前,chartCanvas将是未定义的。 Angular在创建所有视图后运行更改检测。它在创建视图时调用构造函数。所以你在这里试图注入一个组件

  constructor(public navCtrl: NavController, public navParams: NavParams,
     public analyzerChart: AnalyzerChartComponent
    ) {
在Angular运行变更检测之前

。等待变更检测。使用ngAfterViewInit生命周期钩子:

ngAfterViewInit() {
  this.analyzerChart.chartCanvas
}

阅读Everything you need to know about change detection in Angular了解详情。

答案 1 :(得分:0)

我完全错了。而不是尝试注入子组件(就像我曾经在JSF等中那样)我应该使用标准的角度数据绑定,如下所示:

 <analyzer-chart [analyzerResponse]="analyzerResponse"></analyzer-chart>

然后在父组件中设置数据,如下所示:

private analyzerResponse:BacktestResult = xxx;

并响应更改子组件中的事件,如下所示:

 @Input() 
  analyzerResponse:BacktestResult;

  ngOnChanges() {
    console.log('Hello AnalyzerChartComponent::ngOnChangeData');
    if (this.analyzerResponse && this.chartCanvas) {
      if (this.chart) {
        this.chart.destroy();
      }
      this.setupChart(600);
    }
  }

下次我在询问之前完成手册阅读。无论如何,谢谢Maximus!