我正在尝试构建绘制图表的angular2组件(使用
jquery图)
import {Component,ElementRef,Input,OnChanges} from 'angular2/core'; @Component({ selector: 'flot',template: `<div>loading</div>` }) export class FlotCmp implements OnChanges{ private width = '100%'; private height = 220; static chosenInitialized = false; @Input() private options: any; @Input() private dataset:any; @Input() private width:string; @Input() private height:string; constructor(public el: ElementRef) {} ngOnChanges() { if(!FlotCmp.chosenInitialized) { let plotArea = $(this.el.nativeElement).find('div').empty(); plotArea.css({ width: this.width,height: this.height }); $.plot( plotArea,this.dataset,this.options); FlotCmp.chosenInitialized = true; } } }
将图表“data”属性作为输入参数的组件:
<flot [options]="splineOptions" [dataset]="dataset" height="250px" width="100%"></flot>
到目前为止,只要“dataset”是静态变量,我就设法使其工作.
this.dataset = [{label: "line1",color:"blue",data:[[1,130],[3,80],[4,160],[5,159],[12,350]]}];
我的问题是当数据作为承诺时使其工作:
export class App implements OnInit { private dataset:any; public entries; getEntries() { this._flotService.getFlotEntries().then( entries => this.dataset[0].data = entries,error => this.errorMessage = <any>error); } ngOnInit() { this.getEntries() } constructor(private _flotService:FlotService) { this.name = 'Angular2' this.splineOptions = { series: { lines: { show: true },points: { radius: 3,show: true } } }; this.dataset = [{label: "line1",data:null]}]; } }
由于某种原因,数据更改无法投射到“flot”组件
请帮忙
解决方法
除了Günter的答案,另一个选择是在ngDoCheck()中实现你自己的变化检测,当你的数据从服务器返回时将被调用:
ngDoCheck() { if(this.dataset[0].data !== null && !this.dataPlotted) { console.log('plotting data'); let plotArea = $(this.el.nativeElement).find('div').empty(); $.plot( plotArea,this.options); this.dataPlotted = true; } }
我觉得这是一种更简洁的方法,因为我们不必为了满足/触发角度变化检测而以特定的方式编写代码.但唉,它的效率较低. (当发生这种情况时,我讨厌它!)
此外,您在ngOnChanges()中的代码可以移动到ngOnInit().
正如Günter已经提到的那样,不会调用ngOnChanges(),因为填充数据时数据集数组引用不会更改.因此Angular不认为任何输入属性发生了变化,因此不会调用ngOnChanges().无论是否有任何输入属性更改,都会在每个更改检测周期中调用ngDoCheck().
另一种选择是在父组件中使用@ViewChild(FlotCmp),它将获得对FlotCmp的引用.然后父级可以使用该引用在FlotCmp上调用一些方法,比如drawPlot(),以便在数据到达时绘制/更新绘图.
drawPlot(dataset) { console.log('plotting data',dataset); let plotArea = $(this.el.nativeElement).find('div').empty(); $.plot( plotArea,dataset,this.options); this.dataset = dataset; }
这比ngDoCheck()更有效,它没有我上面用ngOnChanges()方法描述的问题.
但是,如果我使用这种方法,我会稍微重做代码,因为我不喜欢数据集当前是一个输入属性,但是drawPlot()获取通过函数参数传入的数据.