Angularjs - Charts.js:相同的图表元素不会在其他视图上重绘

时间:2022-12-04 09:20:33

I am new to angularjs, trying to create my first directive. I am creating a directive to load Charts.js2.0(beta) into my application.

我是angularjs的新手,试图创建我的第一个指令。我正在创建一个指令,将Charts.js2.0(beta)加载到我的应用程序中。

I have 2 views managed by angular-route, both html view has ng-included a html page that contains only charts-element.

我有两个由angular-route管理的视图,两个html视图都包含一个仅包含charts-element的html页面。

The problem is the first page properly draws the chart, when i go to other view the charts div is loaded but charts is not re-drawn. And now if i go back to first view its blank.

问题是第一页正确绘制图表,当我转到其他视图时,图表div被加载但图表不会重新绘制。现在,如果我回去第一次查看它的空白。

Link to Plunker

链接到Plunker

What i am doing wrong? Is there any issue with my directive?

我做错了什么?我的指令有问题吗?

Thanks in advance.

提前致谢。

2 个解决方案

#1


6  

There appears to be an issue with the Charts library modifying the existing object on the root scope, and thereby ignoring it forever afterward. I can't really trace down what is doing it, but here's a fix for you: http://plnkr.co/edit/jDQFV62FSeXAQJ6o7jE8

图表库修改根作用域上的现有对象似乎存在问题,从而在之后永远忽略它。我无法真正追查到底是做什么的,但这里有一个解决方法:http://plnkr.co/edit/jDQFV62FSeXAQJ6o7jE8

Here is what you had

这就是你所拥有的

  scope.$watch('config', function(newVal) {
    if(angular.isDefined(newVal)) {
      if(charts) {
        charts.destroy();
      }
      var ctx = element[0].getContext("2d");
      charts = new Chart(ctx, scope.config);
      //scope.$emit('create', charts);
    }
  });

Above, you can see that you're passing scope.config directly into the charts method. That appears to be modifying the data somehow, and since that's passed by reference, you're actually modifying $rootScope.sales.charts. If you copy that object and use it locally like below, you don't have that problem.

在上面,您可以看到您将scope.config直接传递给charts方法。这似乎是以某种方式修改数据,并且因为它是通过引用传递的,所以实际上是在修改$ rootScope.sales.charts。如果您复制该对象并在本地使用它,如下所示,您就没有这个问题。

Here's how I fixed it.

这是我修复它的方法。

  scope.$watch('config', function(newVal) {
    var config = angular.copy(scope.config);
    if(angular.isDefined(newVal)) {
      if(charts) {
        charts.destroy();
      }
      var ctx = element[0].getContext("2d");
      charts = new Chart(ctx, config);
      //scope.$emit('create', charts);
    }
  });

You can see that instead of passing that object directly in, we use angular to make a copy (angular.copy()), and that's the object we pass in.

您可以看到,不是直接传递该对象,而是使用angular来制作副本(angular.copy()),这就是我们传入的对象。

#2


2  

I think it has relation with the id of the canvas where you are drawing. I've had this problem too amd it was because i was using the same id for the canvas of two graphs in different views. Be sure that those ids are different and that the javasrcipt of each graph is in the controller of each view or in each view itself.

我认为它与您正在绘制的画布的id有关。我有这个问题,因为我在不同的视图中使用相同的id用于两个图形的画布。确保这些ID不同,并且每个图的javasrcipt位于每个视图的控制器中或每个视图中。

Taking a look at your pluker I see that you are using the same html for the graph and I guess that when angular moves from one of your views to the other thinks that the graph is already drawn. Differentiating two graphs will solve the problem. I don't know of there is any other approach that allows using the same html for the canvas of the graph.

看看你的插件,我看到你正在使用相同的html图表,我想当角度从你的一个视图移动到另一个视图时认为图形已经被绘制。区分两个图将解决问题。我不知道有任何其他方法允许使用相同的html作为图形的画布。

Hope it helps you solve it

希望它可以帮助您解决它

#1


6  

There appears to be an issue with the Charts library modifying the existing object on the root scope, and thereby ignoring it forever afterward. I can't really trace down what is doing it, but here's a fix for you: http://plnkr.co/edit/jDQFV62FSeXAQJ6o7jE8

图表库修改根作用域上的现有对象似乎存在问题,从而在之后永远忽略它。我无法真正追查到底是做什么的,但这里有一个解决方法:http://plnkr.co/edit/jDQFV62FSeXAQJ6o7jE8

Here is what you had

这就是你所拥有的

  scope.$watch('config', function(newVal) {
    if(angular.isDefined(newVal)) {
      if(charts) {
        charts.destroy();
      }
      var ctx = element[0].getContext("2d");
      charts = new Chart(ctx, scope.config);
      //scope.$emit('create', charts);
    }
  });

Above, you can see that you're passing scope.config directly into the charts method. That appears to be modifying the data somehow, and since that's passed by reference, you're actually modifying $rootScope.sales.charts. If you copy that object and use it locally like below, you don't have that problem.

在上面,您可以看到您将scope.config直接传递给charts方法。这似乎是以某种方式修改数据,并且因为它是通过引用传递的,所以实际上是在修改$ rootScope.sales.charts。如果您复制该对象并在本地使用它,如下所示,您就没有这个问题。

Here's how I fixed it.

这是我修复它的方法。

  scope.$watch('config', function(newVal) {
    var config = angular.copy(scope.config);
    if(angular.isDefined(newVal)) {
      if(charts) {
        charts.destroy();
      }
      var ctx = element[0].getContext("2d");
      charts = new Chart(ctx, config);
      //scope.$emit('create', charts);
    }
  });

You can see that instead of passing that object directly in, we use angular to make a copy (angular.copy()), and that's the object we pass in.

您可以看到,不是直接传递该对象,而是使用angular来制作副本(angular.copy()),这就是我们传入的对象。

#2


2  

I think it has relation with the id of the canvas where you are drawing. I've had this problem too amd it was because i was using the same id for the canvas of two graphs in different views. Be sure that those ids are different and that the javasrcipt of each graph is in the controller of each view or in each view itself.

我认为它与您正在绘制的画布的id有关。我有这个问题,因为我在不同的视图中使用相同的id用于两个图形的画布。确保这些ID不同,并且每个图的javasrcipt位于每个视图的控制器中或每个视图中。

Taking a look at your pluker I see that you are using the same html for the graph and I guess that when angular moves from one of your views to the other thinks that the graph is already drawn. Differentiating two graphs will solve the problem. I don't know of there is any other approach that allows using the same html for the canvas of the graph.

看看你的插件,我看到你正在使用相同的html图表,我想当角度从你的一个视图移动到另一个视图时认为图形已经被绘制。区分两个图将解决问题。我不知道有任何其他方法允许使用相同的html作为图形的画布。

Hope it helps you solve it

希望它可以帮助您解决它