Фильтр / функция, вызывающая инфдиг - PullRequest
0 голосов
/ 30 сентября 2018

Я делаю круговую диаграмму для моих данных.Я использую 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 каждый раз.Согласно документам , это потому, что я возвращаю новый массив, которым я являюсь, потому что это почти другой набор данных.Даже если я избавлюсь от copy (который должен быть полностью отдельным объектом) и использую input напрямую (input.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 каждый раз?Это то, что я пытаюсь решить.

1 Ответ

0 голосов
/ 01 октября 2018

Как вы указали, вы не можете привязать функцию, которая создает новый массив, или цикл дайджеста никогда не будет удовлетворен тем, что новое значение соответствует старому, потому что ссылка на массив изменяется каждый раз.

Вместо этого привязывайте только данные, а затем внедряйте фильтр в директиву, чтобы отфильтрованные данные никогда не связывались, просто это показано в шаблоне директивы.

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];
    }
});

Я жестко закодировал строки данных / ключей в директивах, но при необходимости вы можете передать их как дополнительные привязки.

Простая макетная скрипка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...