Фильтр / функция, вызывающая infdig

Я делаю круговую диаграмму для своих данных. Я использую Угловая диаграмма (а затем 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? Это то, что я пытаюсь решить.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
57
1

Ответы 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];
    }
});

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

Простой макет скрипки

Другие вопросы по теме