【问题标题】:Filter/Function causing infdig导致 infdig 的过滤器/函数
【发布时间】:2018-09-30 20:23:48
【问题描述】:

我正在为我的数据制作一个饼图。我正在使用Angular Chart(随后是charts.js)。

我的数据看起来像这样(vm 是控制器):

vm.persons = [
  {
    name:'smith',
    cart: [
      {
        id: 1,
        category: 'food'
      },
      {
        id: 2,
        category: 'clothes'
      }
    ]
  },
  {
    name: 'adams',
    cart: [
      {
        id: 3,
        category: 'automobile'
      },
      {
        id:1, category: 'food'
      }
    ]
  }
]

因此,我的模板如下所示:

<div ng-repeat="person in vm.persons">
  <div class="person-header">{{person.name}}</div>
  <!-- chart goes here -->
  <canvas class="chart chart-pie" chart-data="person.cart | chart : 'category' : 'data'" chart-labels="person.cart | chart : 'category' : 'labels'"></canvas>
  <div class="person-data" ng-repeat="item in person.cart">
    <div>{{item.category}}</div>
  </div>
</div>

我决定为图表使用过滤器,因为我认为这合适、干燥且可重复使用:

angular.module('myModule').filter('chartFilter', function() {
  return function(input, datum, key) {
    const copy = JSON.parse(JSON.stringify([...input.slice()])); // maybe a bit overboard on preventing mutation...
    const entries = Object.entries(copy.reduce((o,n) => {o[n[datum]] = (o[n[datum]] || 0) + 1}, {}));
    const out = {
      labels: entries.map(entry => entry[0]);
      data: entries.map(entry => entry[1]);
    };
    return out[key];
  }
});

这可以正常工作,并且图表确实会显示,并带有正确的数据。然而,根据控制台,它每次都会抛出一个infdig error。根据docs,这是因为我要返回一个新数组,因为它几乎是一组不同的数据。即使我摆脱copy(这意味着完全是一个单独的对象)并直接使用inputinput.reduce(o,n)等),它仍然会引发错误。

我也试过把它变成一个函数(在控制器中):

vm.chartBy = (input, datum, key) => {
  const copy = JSON.parse(JSON.stringify([...input.slice()])); // maybe a bit overboard on preventing mutation...
  const entries = Object.entries(copy.reduce((o,n) => {o[n[datum]] = (o[n[datum]] || 0) + 1}, {}));
  const out = {
    labels: entries.map(entry => entry[0]);
    data: entries.map(entry => entry[1]);
  };
  return out[key];
};

在模板中:

<canvas class="chart chart-pie" chart-data="vm.chartBy(person.cart, 'category', 'data')" chart-labels="vm.chartBy(person.cart, 'category', 'labels')"></canvas>

但是,这也会引发 infdig 错误。

有谁知道如何避免每次都出现infdig 错误?这就是我要解决的问题。

【问题讨论】:

    标签: javascript angularjs angular-chart angularjs-infdig


    【解决方案1】:

    正如您所指出的,您不能绑定到生成新数组的函数,否则摘要循环将永远不会满足新值与旧值匹配,因为数组引用每次都会更改。

    相反,只绑定到数据,然后在指令中实现过滤器,这样过滤后的数据永远不会被绑定,只是显示在指令的模板中。

    HTML

    <canvas class="chart chart-pie" chart-data="person.cart" chart-labels="person.cart"></canvas>
    

    JavaScript

    app.directive('chartData', function(){
        return {
            template: '{{chartData | chart : "category" : "data"}}',
            scope: {
                'chartData': '='
            }
        }
    });
    
    app.directive('chartLabels', function(){
        return {
            template: '{{chartLabels | chart : "category" : "labels"}}',
            scope: {
                'chartLabels': '='
            }
        }
    });
    
    app.filter('chart', function() {
        return function(input, datum, key) {
            ...
            return out[key];
        }
    });
    

    我已经在指令中硬编码了数据/键字符串,但如果需要,您可以将它们作为附加绑定传递。

    Simple Mock-up Fiddle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-25
      • 2020-07-11
      • 1970-01-01
      • 2018-04-24
      • 1970-01-01
      • 2012-10-15
      • 1970-01-01
      相关资源
      最近更新 更多