gpt4 book ai didi

javascript - 导致 infdig 的过滤器/函数

转载 作者:行者123 更新时间:2023-12-03 01:02:03 25 4
gpt4 key购买 nike

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

我的数据如下所示( vm 是 Controller ):

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 错误。根据 docs ,这是因为我返回一个新数组,因为它几乎是一组不同的数据。即使我摆脱 copy (这意味着完全是一个单独的对象)并直接使用 input (input.reduce(o,n) 等)它仍然会抛出错误。

我也尝试将其变成一个函数(在 Controller 中):

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 错误?这就是我正在努力解决的问题。

最佳答案

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

相反,仅绑定(bind)到数据,然后在指令中实现过滤器,这样过滤后的数据就不会被绑定(bind),只显示在指令的模板中。

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

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

Simple Mock-up Fiddle

关于javascript - 导致 infdig 的过滤器/函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52581819/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com