我正在进行Angular 4升级并且几乎没有任何问题。我收到以下错误,不知道是什么问题。我可以在risk-tolerance-statements.component
中看到对模块statement-selector.component的引用错误如下
Can't bind to 'riskToleranceStatements' since it isn't a known property of 'rtq-statement-selector'.
1. If 'rtq-statement-selector' is an Angular component and it has 'riskToleranceStatements' input, then verify that it is part of this module.
2. If 'rtq-statement-selector' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component. (" <rtq-statement-selector *ngIf="showStatementSelectPopup"
风险耐受statements.component
import {Component, ViewChild, EventEmitter,ViewContainerRef} from '@angular/core';
import { RunService,ClientService,UserService,AnalyticsService,ModalService} from '@wtw/platform/services';
import { Dto} from '@wtw/platform/api';
import {Observable} from 'rxjs/rx';
import { IAnalyticsSendInput} from '@wtw/platform/interfaces';
import { Base,ChangeTracking as CT} from '@wtw/toolkit';
//import {PdfLinkDirective} from '@wtw/toolkit/directives';
import {Indexer} from '../../interfaces/indexer';
import {OptionsSelectorComponent} from './options-selector/options-selector.component';
import {OptionDisplayComponent} from './option-display/option-display.component';
import {OptionSectionDisplayComponent} from './option-section-display/option-section-display.component';
import {StatementSelectorComponent} from './statement-selector/statement-selector.component';
import {RunViewModel, StatementOption, Metric} from '../../api/generated/RunViewModel';
import {OnForwardNavigation} from '@wtw/platform/interfaces';
import {MetricChartComponent} from '../../shared/charts/metric-chart.component';
import {CoreModalComponent} from '@wtw/platform/components/core-modal/core-modal.component';
@Component({
moduleId: module.id,
templateUrl: 'risk-tolerance-statements.component.html',
styleUrls: ['../../shared/style/site.css', '../../styles/rtc.css']
})
export class RiskToleranceStatementsComponent extends Base.ReactiveComponent implements OnForwardNavigation {
metricMap: Indexer<Metric> = {};
runInformation: Dto.RunInfo;
runModel: RunViewModel;
selectedOption: StatementOption;
metricChartOptions: any = JSON.parse("{ \"chart\": { \"height\":260, \"type\":\"scatter\",\"marginTop\":30 },\"title\": { \"text\": \"\"}, \"legend\": {\"enabled\":false},\"credits\": {\"enabled\": false},\"series\": [{},{ \"type\": \"scatter\", \"marker\": {\"enabled\": false}}], \"xAxis\":{\"endOnTick\": true, \"startOnTick\": true, \"minPadding\": 0.2, \"maxPadding\": 0.2,\"labels\":{\"enabled\":true},\"gridLineWidth\": 0,\"gridLineColor\": \"black\",\"minorGridLineWidth\": 0,\"tickColor\": \"black\",\"title\":{\"text\":\"Size of Loss\",\"useHtml\":true}}, \"yAxis\":{\"startOnTick\":true,\"tickInterval\":5, \"endOnTick\":true,\"min\":0,\"labels\":{\"enabled\":true},\"title\": {\"text\": \"Metric Scores Before Loss\",\"useHtml\":true,\"align\":\"high\",\"rotation\":0,\"y\":-15,\"offset\":-110}}, \"plotOptions\": { \"scatter\": {\"marker\": { \"radius\": 15,\"enabled\": true}}},\"tooltip\": {\"enabled\":true,\"pointFormat\": \"score:{point.y}value:{point.x}\"} }");
riskToleranceStatementChartOptions: any = {
showSlider: false,
showPlotLineLabel: true,
isStressTest: false
};
selectedStatementOptionDisplay: StatementOption;
showStatementSelectPopup = false;
showModifyOptionPopup = false;
statementsSelectedEvent = new EventEmitter<any>();
statementsSelectedObservable: () => Promise<any>;
riskToleranceStatements: StatementOption[];
bellCurveChartData: any = {};
selectedOptionId: number;
selectedComment: StatementOption;
currencyInformation: Dto.CurrencyInfo;
@ViewChild(MetricChartComponent) private metricChartComponent: MetricChartComponent;
//@ViewChild(PdfLinkDirective) private pdfDirective: PdfLinkDirective;
constructor(private viewRef:ViewContainerRef,public runService: RunService, private _modalService: ModalService, private googleAnalyticSevice: AnalyticsService, private clients: ClientService, private user: UserService) { super(); }
ngOnInit() {
const runServiceSubscription = this.runService.activeRun
.filter((run: any) => !!run)
.subscribe((run: any) => {
this.runInformation = run.info;
this.currencyInformation = run.currencyInfo;
this.updateRunModel(run.data);
this.bellCurveChartData = {
options: run.data.chartDefinitions.metricPickerChartOptions,
data: run.data.chartDefinitions.bellCurveChartData
}
});
this._subscriptions.push(runServiceSubscription);
this.statementsSelectedObservable = this.getstatementSeletedObservable;
this.triggerGoogleAnanlyticsEvent();
}
reload(run: RunViewModel) { // After currency change
this.updateRunModel(run);
this.metricChartComponent.reloadChart(run);
this.updateSelectedRiskToleranceThreshold();
}
apply() {
this.runService.executeTrigger(this.runInformation.runId, this.runModel, 3, this.currencyInformation, 'risk-tolerance-statements');
this.triggerGoogleAnanlyticsEvent();
}
/**
* Function to push to the platform to be envoked when the pdf button is clicked.
* The promise chain to be resolved with statement selector popup close event
*/
getstatementSeletedObservable = () => {
const applyOptionIdsPromise: Promise<any> = new Promise((resolve: any) => {
this.runModel.riskToleranceStatements.options = this.riskToleranceStatements
.map((option: StatementOption, index: number) => {
option.id = index;
return option;
});
resolve();
});
const saveRunPromise: Promise<any> = this.runService
.persist(this.runInformation.runId, this.runModel, this.currencyInformation, null, true)
.do(() => this.showStatementSelectPopup = true)
.do(() => console.debug('Run saved'))
.toPromise();
const selectedStatementEventPromise = this.statementsSelectedEvent.take(1).toPromise();
return Promise.all([applyOptionIdsPromise, saveRunPromise, selectedStatementEventPromise])
.then((retVals) => retVals[2]);
};
optionSelected(option: StatementOption) {
this.riskToleranceStatements.map((statement: StatementOption) => {
statement.selected = statement.id === option.id;
});
this.refresh();
}
optionRemoved(option: StatementOption) {
this._modalService.confirm(this.viewRef,'MODAL.TEST')
.then((shouldRemove: boolean) => {
if (shouldRemove) this.removeOption(option);
});
}
statementsSelected(selectResult: any) {
this.statementsSelectedEvent.emit(selectResult);
this.showStatementSelectPopup = false;
}
showOptionDiplayPopup(statementOption?: StatementOption) {
if (!statementOption) {
statementOption = (Object.assign({}, this.runModel.riskToleranceStatements.vanillaOption) as StatementOption);
statementOption.selected = false;
statementOption.id = null; // New, unconfirmed option. No Id set until form complete
}
this.selectedStatementOptionDisplay = statementOption;
this.showModifyOptionPopup = true;
}
optionChange(selectedOption: StatementOption) {
this.showModifyOptionPopup = false;
let runMatlabApply = false;
if (!selectedOption) return; // cancelled change, just ignore
this.riskToleranceStatements.map((option: StatementOption) => option.selected = false);
selectedOption.selected = true;
if (!selectedOption.id) {
// new option
selectedOption.id = (this.riskToleranceStatements.length + 1) || 1;
this.riskToleranceStatements.push(selectedOption);
runMatlabApply = true;
} else {
// modified option
let selectedRiskToleranceIndex: number;
const matchingOption = this.riskToleranceStatements.find((option: StatementOption, index: number) => {
if (option.id !== selectedOption.id) return false;
selectedRiskToleranceIndex = index;
return true;
});
if (!matchingOption) throw new Error("Unable to find matching statement option from display");
runMatlabApply = matchingOption.riskToleranceThreshold !== selectedOption.riskToleranceThreshold || matchingOption.selectedTimeHorizon !== selectedOption.selectedTimeHorizon;
this.riskToleranceStatements[selectedRiskToleranceIndex] = selectedOption;
}
this.refresh();
if (runMatlabApply) this.apply();
}
private updateRunModel(run: RunViewModel) {
this.runModel = run;
this.runModel.metrics.map(m => this.metricMap[m.id] = m);
this.riskToleranceStatements = this.runModel.riskToleranceStatements.options || [];
this.metricChartComponent.reloadChart(this.runModel);
if (!this.riskToleranceStatements.length) return this.showOptionDiplayPopup();
const selectedOption = this.riskToleranceStatements.find((option: StatementOption) => {
return option.selected;
});
if (!selectedOption) {
this.selectedOption = this.riskToleranceStatements[0];
this.selectedOption.selected = true;
}
this.metricChartComponent.reloadChart(this.runModel);
this.refresh();
}
private generateChartPlotlines(): any[] {
const plotItems = this.riskToleranceStatements
.filter((option: StatementOption) => {
return !!option.riskToleranceThreshold;
})
.map((option: StatementOption, index: number) => {
return {
value: option.riskToleranceThreshold,
label: index + 1,
focus: option.selected,
index: index
};
});
return plotItems;
}
private removeOption(option: StatementOption) {
if (option) {
this.riskToleranceStatements = this.riskToleranceStatements.filter((statement: StatementOption) => {
return statement.id !== option.id;
});
this.runModel.riskToleranceStatements.options = this.riskToleranceStatements.filter((statement: StatementOption) => {
return statement.id !== option.id;
});
this.runService
.persist(this.runInformation.runId, this.runModel, this.currencyInformation, null, true)
}
this.refresh();
}
private updateSelectedRiskToleranceThreshold() {
this.riskToleranceStatements
.filter((option) => option.selected)
.map((option) => this.selectedOption = option);
}
private refresh() {
this.reassignStatementIds();
const chartPlotLines = this.generateChartPlotlines();
this.metricChartComponent.refreshPlotlines(chartPlotLines);
// if (this.pdfDirective) this.pdfDirective.beforeGenerate = this.getstatementSeletedObservable;
}
private reassignStatementIds() {
this.riskToleranceStatements.map((option: StatementOption, index: number) => {
option.id = index + 1;
});
var statements: StatementOption[] = JSON.parse(JSON.stringify(this.riskToleranceStatements));
var actualSelected = statements.find(o => o.selected);
var sorted = statements.sort((pre, curr) => pre.riskToleranceThreshold - curr.riskToleranceThreshold);
this.selectedOptionId = sorted.indexOf(actualSelected) + 1;
this.selectedComment = actualSelected;
this.runModel.riskToleranceStatements.options = this.riskToleranceStatements;
}
onForwardNavigation(): void {
}
triggerGoogleAnanlyticsEvent() {
let sendInput:IAnalyticsSendInput= {
eventAction:'Risk Tolerance Statements Trigger',
eventCategory:'Trigger',
runId:this.runInformation.runId,
addtionalFields:{
user: this.user.currentUserInfo.encryptedUser,
clientId:this.runInformation.clientId
}
}
this.googleAnalyticSevice.send(sendInput,true);
}
}
语句selector.component
import {EventEmitter, Output, Input, OnInit, Component} from '@angular/core'
//import {ToastsManager} from 'ng2-toastr';
import {StatementOption, SelectOption} from '../../../api/generated/RunViewModel';
import {RoundCheckboxComponent} from '../../../shared/round-checkbox/round-checkbox.component';
@Component({
moduleId: module.id,
selector: 'rtq-statement-selector',
templateUrl: 'statement-selector.component.html',
// directives: [
// RoundCheckboxComponent
// ],
styleUrls: ['statement-selector.component.css']
})
export class StatementSelectorComponent implements OnInit {
statements: any[];
@Input() maxStatements: number = 3;
@Input() private riskToleranceStatements: StatementOption[] = [];
@Output() complete: EventEmitter<any> = new EventEmitter<any>();
// constructor(private toastr: ToastsManager) { }
ngOnInit(): any {
this.statements = this.riskToleranceStatements.map((statement: any, index: number): any[] => {
const item = statement;
item.isSelected = (index + 1) <= this.maxStatements;
const selectedCompany = statement.company.find((company: SelectOption) => {
return company.selected;
});
if (selectedCompany && selectedCompany.friendlyName) item.selectedCompany = selectedCompany.friendlyName;
return item;
});
}
cancelClicked() {
this.complete.emit(false);
}
okClicked() {
const selectedIds = this.statements
.filter((statement: any) => statement.isSelected)
.map((statement: any) => statement.id)
.join(",");
const selectedStatementIds = { selectedStatementIds: selectedIds };
this.complete.emit(selectedStatementIds);
}
togs(statement: any) {
const isSelected: boolean = statement.isSelected;
const selectedCount = this.statements
.filter((statement: any) => {
return statement.isSelected;
})
.length;
if (isSelected) {
if (selectedCount <= 1) { return; }
} else {
if (this.maxStatements && selectedCount === this.maxStatements) { return; }
}
statement.isSelected = !isSelected;
}
}
风险耐受statements.component.html
<div id="pageConstrainer">
<div class="grid" style="position: fixed; width: inherit; max-width: inherit; z-index: 5">
<div class="col-dt-1 col-ipl-1 col-ipp-1" style="padding-right: 0px;">
<!--<a pdf-link="risk-tolerance-statement-report" [runId]="runInformation?.runId" [beforeGenerate]="statementsSelectedObservable" style="display: block; position: absolute; right: 3px; top: 3px;"></a>-->
<currency-selector (selectedCurrencyChange)="reload($event.run)"></currency-selector>
</div>
</div>
<div class="grid grid-padded" style="padding-top: 32px;">
<rtq-statement-selector *ngIf="showStatementSelectPopup" (complete)="statementsSelected($event)" [riskToleranceStatements]="riskToleranceStatements"></rtq-statement-selector>
<rtq-option-display *ngIf="showModifyOptionPopup" [option]="selectedStatementOptionDisplay" [timeHorizons]="runModel?.riskToleranceStatements?.timeHorizons" (optionDisplayStatusChange)="optionChange($event)"></rtq-option-display>
<div class="grid padded" style="background-color:#efeede;">
<div class="col-dt-1 col-ipl-1 col-ipp-1 module">
<div class="module-header">
{{'STRESS_TEST_PAGE.SIZE_OF_LOSS.HEADER'|translate}}
<template #sizeOfLossHtmlTooltip>
<span [innerHTML]="'TOOLTIPS.STRESS_TEST.SIZE_OF_LOSS'|translate"></span>
</template>
<span class="help" style="margin-top: -10px;" [tooltip]="sizeOfLossHtmlTooltip"></span>
</div>
<div class="module-content border" style="min-height: 260px; position: relative">
<metric-chart [runModel]="runModel" [options]="riskToleranceStatementChartOptions" [chartOptions]="metricChartOptions"></metric-chart>
</div>
</div>
</div>
<div class="grid padded">
<div class="col-dt-1-4 col-ipl-1-4 col-ipp-1-4">
<div class="sectionLabel left" [textContent]="'GENERAL.COMMENTS'|translate"></div>
<br/>
<br/>
<rtq-options-selector (optionRemoved)="optionRemoved($event)" *ngIf="riskToleranceStatements" [vanillaOption]="runModel?.riskToleranceStatements?.vanillaOption" [options]="riskToleranceStatements" (optionSelected)="optionSelected($event)" (optionEditDisplayClick)="showOptionDiplayPopup($event)"></rtq-options-selector>
</div>
<div class="module col-dt-3-4 col-ipl-3-4 col-ipp-3-4">
<div class="module">
<div class="module-header">
Area of Concern Score After Threshold Event(s)
<!--<span class="help" [tooltip]="'TOOLTIPS.STRESS_TEST.SIZE_OF_LOSS'|translate"></span>-->
</div>
<div class="module-content border">
<rtq-option-section-display [commentSections]="runModel?.commentSections"
[sections]="runModel?.sections"
[selectedCommentId]="selectedOptionId"
[selectedComment]="selectedComment"></rtq-option-section-display>
</div>
</div>
</div>
</div>
</div>
</div>
语句选择器-component.html
import {EventEmitter, Output, Input, OnInit, Component} from '@angular/core'
//import {ToastsManager} from 'ng2-toastr';
import {StatementOption, SelectOption} from '../../../api/generated/RunViewModel';
import {RoundCheckboxComponent} from '../../../shared/round-checkbox/round-checkbox.component';
@Component({
moduleId: module.id,
selector: 'rtq-statement-selector',
templateUrl: 'statement-selector.component.html',
// directives: [
// RoundCheckboxComponent
// ],
styleUrls: ['statement-selector.component.css']
})
export class StatementSelectorComponent implements OnInit {
statements: any[];
@Input() maxStatements: number = 3;
@Input() private riskToleranceStatements: StatementOption[] = [];
@Output() complete: EventEmitter<any> = new EventEmitter<any>();
// constructor(private toastr: ToastsManager) { }
ngOnInit(): any {
this.statements = this.riskToleranceStatements.map((statement: any, index: number): any[] => {
const item = statement;
item.isSelected = (index + 1) <= this.maxStatements;
const selectedCompany = statement.company.find((company: SelectOption) => {
return company.selected;
});
if (selectedCompany && selectedCompany.friendlyName) item.selectedCompany = selectedCompany.friendlyName;
return item;
});
}
cancelClicked() {
this.complete.emit(false);
}
okClicked() {
const selectedIds = this.statements
.filter((statement: any) => statement.isSelected)
.map((statement: any) => statement.id)
.join(",");
const selectedStatementIds = { selectedStatementIds: selectedIds };
this.complete.emit(selectedStatementIds);
}
togs(statement: any) {
const isSelected: boolean = statement.isSelected;
const selectedCount = this.statements
.filter((statement: any) => {
return statement.isSelected;
})
.length;
if (isSelected) {
if (selectedCount <= 1) { return; }
} else {
if (this.maxStatements && selectedCount === this.maxStatements) { return; }
}
statement.isSelected = !isSelected;
}
}
答案 0 :(得分:0)
您riskToleranceStatements
属性被标记为私有,因此无法在模板中使用。修复方法是将其设为 public 属性。