Highcharts系列数据不会通过角度路径变化持续存在

时间:2016-06-10 14:33:57

标签: javascript angularjs highcharts

我在AngularJS中使用Highcharts。我有一个生成图表的指令。在链接函数中,我指定了一个默认对象chartOptions。设置默认选项后,我将该对象附加到另一个传递给指令的对象,该对象在路由和刷新之间保持passedObject。因此,成功附加后对chartOptions的任何更改都会保留。然后通过调用Highcharts.chart();

生成图表
return {
    restrict: 'E',
    scope: {
        passedObject: "="
    },
    link: function (scope, element) {

        var chartOptions = {
            title : {
             text: 'sample report'
            }
            ...
        }

        scope.passedObject.chartOptions = scope.passedObject.chartOptions || chartOptions;

        var chart = Highcharts.chart(element[0], scope.passedObject.chartOptions);
    }

    // successfully add new series
    // series rendered immediately but does not persist though view changes and page reload.
    scope.addSeries = function(seriesObject){
        scope.elementObject.chart.addSeries(seriesObject);
    };

    // successfully pushes object to array
    // does not immediately render because Highchart doesn't see change 
    // but does render after reloading because Highchart checks options again
    // Does not render with animation like addSeries() API does.
    scope.addSeriesNoAPI = function(seriesObject){
       scope.elementObject.chart.series.push(seriesObject);
    };
}

第一次生成图表没有问题,如果我返回到此视图,图表将再次生成相同的默认选项。

但是,如果我使用Highcharts API以编程方式添加新数据系列chart.addSeries(newSeriesObject),则系列会添加并在图表上呈现,但不会在路由和刷新之间保持不变。

如果我通过直接JS chartOptions手动将系列对象添加到我的scope.passedObject.chartOptions.series.push(newSeriesObject),该对象将成功推送到数组并将保持不变,但图表不会自动更新,因为它不知道series数组已更改,这显然是API存在的原因。

经过仔细检查,看来Highchart的addSeries()函数正在将新对象推送到某个数组,而不是我持久存在的数组,但我无法弄清楚如何让它工作。

我假设这行代码:var chart = Highcharts.chart(element[0], scope.passedObject.chartOptions);会将图表绑定到scope.passedObject.chartOptions对象,这样当addSeries()函数添加新系列时,会添加它进入scope.passedObject.chartOptions。在记录和观察对象之后,情况似乎并非如此。

1 个答案:

答案 0 :(得分:1)

一种方法是将数据保存在根范围内(但这不是最佳方式)。

另一种方法是使用角度服务来存储这些数据。并在您需要的地方提供此服务。

更改视图/页面时,与控制器不同的角度服务不会被重置。

我建议你创建一个存储图表选项的角度服务,它有一个图表选项对象,一个getter和一个setter。您还可以保留在此服务中对图表对象进行更改的功能。

在您的情况下,您似乎对控制器中的图表对象进行了操作(在您从服务获取它之后?),如果是这样,您将不得不将新对象设置回服务。

当我说服务时我的意思是这样的:

app.service('highChartService', function() {
  var chartOptions;
  var highChartServiceObj = {};

  highChartServiceObj.getChartOptions = function() {
      return chartOptions;
  };

  highChartServiceObj.setChartOptions = function (options) {
     chartOptions = options;
  };

  highChartServiceObj.computeChartObject = function () {
    //do some computation
  }

  return highChartServiceObj;

});

将以上服务添加到您的指令中,并在进行任何更改时使用它来更新您的highchart对象。

另外,如果我没有错,你想要做的是添加像这样chart.addSeries(newSeriesObject)的新系列对象,它解决了你的高图困境。为什么不在下一步更新您的图表对象:scope.passedObject.chartOptions.series.push(newSeriesObject)?虽然如果我这样做,我宁愿将其作为服务的一部分,但所有的高级操作只是服务的一部分,我将在上面的服务中有这样的功能:

highChartServiceObj.updateChart(newSeriesObject, chart) {
   chartOptions.series.push(newSeriesObject);
   chart.addSeries(newSeriesObject);
}