无法绑定到'options',因为它不是"图表"的已知属性,同时在角度 4 中通过 aot 构建



我正在开发angular 4应用程序。我最近介绍了aot。当我进行正常构建时,应用程序构建良好,但当我进行aot构建时会失败。

我收到以下错误消息

Can't bind to 'options' since it isn't a known property of 'chart'. ("<chart [ERROR ->][options]="options" (load)="getInstance($event.context)"></chart>"): ng:///C:/Development/Risk.Analytics.Captives/Clientside/captives/src/app/shared/Highcharts/box-plot-chart/box-plot-chart.component.ts.BoxPlotChartComponent.html@0:7
'chart' is not a known element:
1. If 'chart' is an Angular component, then verify that it is part of this module.

我已经创建了一个共享模块,它被导入app.module和pdf.module中。我有共享模块的highchart组件,因为它们被pdf和app模块使用。然而,chartmodule是在应用程序和pdf模块中声明的

共享模块

import { NgModule } from '@angular/core';
import { ToolkitModule } from '@wtw/toolkit';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { AllComponentsModule } from '@wtw/platform/components';
import { BoxPlotChartComponent } from './shared/Highcharts/box-plot-chart/box-plot-chart.component';
import { HistogramChartComponent } from './shared/Highcharts/histogram/histogram-chart.component';
import { SplineChartComponent } from './shared/Highcharts/spline/spline-chart.component';
import { DynamicFieldComponent } from './shared/dynamic-field/dynamic-field.component';
import { IndustrySelectionComponent } from './shared/industry-selection/industry-selection.component';
import { EsriMapComponent } from './shared/esri-map/esri-map.component';
import { NetPresentValueAnalysisProjectionComponent } from './pages/feasibility/results/net-present-value-analysis/projection/net-present-value-analysis-projection.component';
import { ProjectionTableComponent } from './pages/feasibility/results/projection-table/projection-table.component';
export const SHARED_COMPONENTS = [
BoxPlotChartComponent,
SplineChartComponent,
HistogramChartComponent,    
DynamicFieldComponent,
IndustrySelectionComponent,
EsriMapComponent,
NetPresentValueAnalysisProjectionComponent,
ProjectionTableComponent
];
@NgModule({
imports: [
AllComponentsModule,
CommonModule,
TranslateModule,
ToolkitModule
],
declarations: SHARED_COMPONENTS,
exports: SHARED_COMPONENTS
})
export class SharedModule { }

app.module

import { ChartModule } from 'angular2-highcharts';
import { HighchartsStatic } from 'angular2-highcharts/dist/HighchartsService';
import { SharedModule, SHARED_COMPONENTS } from './shared.module';
const ROOT_COMPONENTS = [
...PLATFORM_COMPONENTS,
...SCORECARD_COMPONENTS,
CaptivesComponent,
DomicileSelectionComponent,
AssumptionsComponent,
...LINES_COMPONENTS,
...RESULTS_COMPONENTS
];
export function highchartsFactory() {
const hc = require('highcharts');
const hb = require('highcharts-histogram-bellcurve');
const dd = require('highcharts/modules/drilldown');
const hcMore = require('highcharts/highcharts-more');
const exp = require('highcharts/modules/exporting');
hcMore(hc);
hb(hc);
dd(hc);
exp(hc);
return hc;
}
declare var require: any;
@NgModule({
declarations: [...ROOT_COMPONENTS ],
imports: [
ChartModule, SharedModule 
],
providers: [...WEBAPI_PROVIDERS, ...SERVICES, {
provide: HighchartsStatic,
useFactory: highchartsFactory
}],
bootstrap: [PlatformRootComponent],
entryComponents: [...SHARED_COMPONENTS, ...ROOT_COMPONENTS]
})
export class AppModule { }

pdf模块

import { NgModule } from '@angular/core';
import { ChartModule } from 'angular2-highcharts';
import { HighchartsStatic } from 'angular2-highcharts/dist/HighchartsService';
import * as  BackendProxy from './api/proxies';
import { PdfRootModule } from '@wtw/platform/pdf';
import { PdfPage } from './pdf/pdf.component';
import { PdfDomicilePage } from './pdf/pdf.domiciles.component';
import { PdfResultsPage } from './pdf/pdf.results.component';
import { PdfResultsPageHeader } from './pdf/pdf.results.page-header/pdf.results.page-header.component';
import { PdfResultsPageFooter } from './pdf/pdf.results.page-footer/pdf.results.page-footer.component';
import { PdfResultsContents }  from './pdf/pdf.results.contents/pdf.results.contents.component';
import { PdfResultsStrategy }  from './pdf/pdf.results.strategy/pdf.results.strategy.component';
import { PdfResultsStrategyHeader }  from './pdf/pdf.results.strategy-header/pdf.results.strategy-header.component';


import { WEBAPI_PROVIDERS } from './api/proxies';
import { ScorecardService, StrategyService, PdfDataService } from './services';
import { SharedModule } from './shared.module';
export function highchartsFactory() {
const hc = require('highcharts');
const hb = require('highcharts-histogram-bellcurve');
const dd = require('highcharts/modules/drilldown');
const hcMore = require('highcharts/highcharts-more');
hcMore(hc);
hb(hc);
dd(hc);
return hc;
}
declare var require: any;
@NgModule({
declarations: [PdfPage, PdfDomicilePage, PdfResultsPage,
PdfResultsPageHeader, PdfResultsPageFooter, PdfResultsContents,
PdfResultsStrategy, PdfResultsStrategyHeader],
imports: [
PdfRootModule, ChartModule , SharedModule
],
providers: [...WEBAPI_PROVIDERS,
{ provide: HighchartsStatic, useFactory: highchartsFactory },
BackendProxy.ScorecardProxy, StrategyService,
BackendProxy.ReferenceProxy, ScorecardService, PdfDataService
],
bootstrap: [PdfPage],
entryComponents: []
})
export class PdfModule { }

方框图组件

import { Component, Input, OnInit } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { ShortNumberFormatPipe } from '@wtw/toolkit';

@Component({
selector: 'app-box-plot-chart',
template: '<chart [options]="options" (load)="getInstance($event.context)"></chart>',
styles: [`
chart{
display: block;
width: 95% !important;
padding:0;
}
`]
})
//, width: number
export class BoxPlotChartComponent implements OnInit {
static chart(shortNumberFormatPipe: ShortNumberFormatPipe, translate: TranslateService, moduleName: string, height: number, width: number, marginTop: number,  graphLegendTitle: string) {
return {
chart: {
type: 'boxplot',
reflow: true,
height: height,
width: width,
marginTop: marginTop
},
title: {
text: ''
},
legend: {
enabled: false
},
exporting: {
chartOptions: {
legend: {
allowHTML: true,
enabled: true,
margin: 25,
itemMarginTop: 0,
symbolRadius: 0,
symbolHeight: 20,
symbolWidth: 20,
useHTML: true,
align: 'right',
verticalAlign: 'bottom',
title: {
text: '',
}
},
chart: {
height: 500,
xAxis: {},
events: null }
}
},
credits: {
enabled: false
},
xAxis: {
lineWidth: 0,
minorGridLineWidth: 0,
lineColor: 'transparent',
labels: {
enabled: false
},
minorTickLength: 0,
tickLength: 0
},
tooltip: {
shared: false,
useHTML: true,
formatter: function() {
let isMillionNumber: boolean = false;
const row = function(label, value) {
const key = 'CAPTIVES.RESULTS.COMMON.';
return '<tr><td style="font-size:10px;">' + translate.instant(key + label) + ': </td>'
+ '<td style="font-size:10px;"><b>' + value + '</b></td></tr>';
};
const transformNumber = function(value) {
isMillionNumber = validateMillionNumber(value);
if (isMillionNumber || moduleName === 'eva')
return shortNumberFormatPipe.transform(value, 2);
else
return shortNumberFormatPipe.transform(value, 0);
};
const table = function(format, point) {
let txt = '<strong style="font-size:12px;color:' + point.color + '">' + point.series.name + '</strong><br><br>';
txt += '<table>';
if (moduleName === 'npv') {
txt += row('HIGH', format(point.high));
txt += row('Q3', format(point.q3));
txt += row('MEDIAN', format(point.median));
txt += row('Q1', format(point.q1));
txt += row('LOW', format(point.low));
} else if (moduleName === 'eva') {
txt += row('HIGH', format(point.high) + '%');
txt += row('Q3', format(point.q3) + '%');
txt += row('MEDIAN', format(point.median) + '%');
txt += row('Q1', format(point.q1) + '%');
txt += row('LOW', format(point.low) + '%');
}
txt += '</table>';
return txt;
};
let point = this.point;
return table(transformNumber, point);
function validateMillionNumber(millionNumber: number) {
return millionNumber >= 1000000;
}
},
},
series: []
};
}
public options: any;
chart: any;
@Input() public series: any;
@Input() public moduleName: string = '';
@Input() public height: number = 400;
@Input() public width: number;
@Input() public marginTop: number;
private shortNumberFormatPipe = new ShortNumberFormatPipe();
constructor(private _translate: TranslateService) {
}
ngOnInit() {
this.loadChart();
}
loadChart() {
let graphLegendTitle: string = this._translate.instant('CAPTIVES.RESULTS.COMMON.GRAPH_LEGEND_TITLE');
this.options = BoxPlotChartComponent.chart(this.shortNumberFormatPipe, this._translate, this.moduleName, this.height, this.width, this.marginTop, graphLegendTitle);
}
getInstance(chartInstance): void {
this.chart = chartInstance;
this.redraw();
}

ngOnChanges(data: any) {
if (!data.series.currentValue || !this.chart) return;
data.series.currentValue.map(s => {
this.chart.addSeries(s);
});
this.loadChart();
this.chart.reflow();
}
redraw() {
if (!this.chart) return;
this._redrawLogic(this.series);
this.chart.redraw();
}
private _redrawLogic(series: any) {
let seriesLength = this.chart.series.length;
for (let i = seriesLength - 1; i > -1; i--) {
this.chart.series[i].remove();
}
series.map(s => {
if (s !== null) {
this.chart.addSeries(s);
}
});
const elements = document.querySelectorAll('.highcharts-legend-item path');
for (let i = 0; i < elements.length; i++) {
elements[i].setAttribute('stroke-width', '20');
elements[i].setAttribute('stroke-height', '20');
}
}
}

您可能需要尝试"forRoot",以确保所有依赖模块都包含在ChartModule:中

ChartModule.forRoot(require('highcharts')

(如文档示例所示:https://www.npmjs.com/package/angular2-highcharts)

在管理多个模块时,模块"forRoot"导入值得理解:https://medium.com/@chrishouse/何时使用根部角度-方法-400094a0ebb7

(如果两个模块都需要ChartModule,您可能想将其移动到SharedModule?(

最新更新