I'm trying to create a list of data items that have first been filtered by value, then sorted by descending value, then sliced to only show the top 5 items. I'm using an Angular factory to return these values to my controller, so that I can display the values in the DOM.

我正在尝试创建一个首先按值过滤的数据项列表,然后按降序值排序,然后切片以仅显示前5项。我正在使用Angular工厂将这些值返回给我的控制器,以便我可以在DOM中显示这些值。

I've been successful in sorting and slicing the data, but I'm running into problems when I run dataHandler.filter. I get the error: 'Cannot read property 'slice' of undefined'.

我已经成功地对数据进行了排序和切片,但是当我运行dataHandler.filter时遇到了问题。我得到错误:'无法读取'undefined'属性'slice'。

Here is my controller where I try to return a new list after running each of these functions:

这是我的控制器,我在运行每个函数后尝试返回一个新列表:

Controller

getData().then(function(data) {

    function updateChart() {
        // get match value
        var filterValue = inputService.primaryInputs[0]["value"];

        // plug match value into filter ** should return only data items with matches
        var filtered = dataHandler.filter(data, "Description", filterValue);

        // sort by descending value "percent"
        var sorted = dataHandler.sort.descending(filtered, "Percent");

        // return top 5 results
        var sliced = dataHandler.slice(sorted, 5);
        $scope.barData = sliced;
    }
    updateChart();

});

I know that dataHandler.sort.descending and dataHandler.slice or working correctly, because I can use data as an argument in dataHandler.sort.descending and the list is returned perfectly. However, when I try to plug use filtered, I get 'Cannot read property 'slice' of undefined'.

我知道dataHandler.sort.descending和dataHandler.slice或正常工作,因为我可以在dataHandler.sort.descending中使用数据作为参数,并且列表被完美地返回。但是,当我尝试插入使用过滤时,我得到'无法读取属性'切片'未定义'。

Factory

app.factory('dataHandler', function ($rootScope) {
    return {
        filter: function(data, dataProp, input) {
            data.filter(function(value, index, array) {
                console.log(value[dataProp] == input);
                return value[dataProp] == input;
            });
        },
        sort: {
            ascending: function (data, sortCriteria) {
                if (data) {
                    data.sort(function (a, b) {
                        return a[sortCriteria] - b[sortCriteria];
                    });
                };
                return data;
            },
            descending: function (data, sortCriteria) {
                if (data) {
                    data.sort(function (a, b) {
                        return b[sortCriteria] - a[sortCriteria];
                    });
                };
                return data;
            }
        },
        slice: function (data, howMany) {
            if (howMany) {
                return data.slice(0, howMany);
            } else {
                return data;
            }
        }
    };

Again - I want to use dataHandler.filter to return a new list with only the items whose Description values match the filterValue.

再次 - 我想使用dataHandler.filter返回一个新列表,其中只包含其Description值与filterValue匹配的项目。

1 个解决方案

#1


1

The reason it doesn't work is because you aren't returning anything in your dataHandler.filter function.

它不起作用的原因是因为您没有在dataHandler.filter函数中返回任何内容。

It should be:

它应该是:

filter: function(data, dataProp, input) {
  return data.filter(function(value, index, array) {
    console.log(value[dataProp] == input);
    return value[dataProp] == input;
  });
}

Remember that Array.prototype.filter does not work in place, like Array.prototype.reverse.

请记住,Array.prototype.filter不能正常工作,例如Array.prototype.reverse。


Even though this will work, I would suggest that you don't actually need a factory for these tasks. Filtering, slicing and sorting are very general purpose tasks and there is no need to wrap around the native implementation (unless you are polyfilling).

尽管这会起作用,但我建议你实际上并不需要工厂来完成这些任务。过滤,切片和排序是非常通用的任务,不需要包含本机实现(除非您是polyfilling)。

I would rewrite the entire factory as a service of reusable transform functions that can be used in a series of chained operations.

我会将整个工厂重写为可重用转换函数的服务,可以在一系列链接操作中使用。

.service('Transform', function() {
  // we will pass this to filter
  this.propEquals = function(property, value) {
    return function(data) {
      return data[property] === value;
    };
  };

  // we'll pass this to sort
  this.sort = function(criteria, ascending) {
    return function(a, b) {
      return ascending?
        a[criteria] - b[criteria] : b[criteria] - a[criteria];
    };
  };
})

Then your updateChart method becomes.

然后你的updateChart方法变成了。

function updateChart() {
  var filterValue = inputService.primaryInputs[0]["value"];

  $scope.barData = data
    .filter(Transform.propEquals("description", filterValue))
    .sort(Transform.sort("Percent", false))
    .slice(0, 5);
}

更多相关文章

  1. React:更新列表中的一个项目而不重新创建所有项目
  2. AngularJS(1.5.8) - 如何直接从获取json对象的控制器中填充选择选
  3. 将子属性添加到jsdoc中的现有属性列表
  4. python数据类型二(列表和元组)
  5. 使用特定顺序的ID列表从Django数据库中获取记录
  6. python传递列表作为函数参数
  7. Python基础(列表)第三天
  8. 用户输入从.csv文件生成新列表?
  9. 从Python中的列表元素中删除URL

随机推荐

  1. android 之 install Location
  2. java解析json字符串的两种方法详解(Andro
  3. Android 输入限制
  4. 非一般的原因:Unable instantiate applica
  5. 实现Android简单动画旋转案例
  6. Android用户界面 UI组件--自动提示输入框
  7. OpenCV4Android开发之旅(一)----OpenCV2.
  8. android设定手机的显示模式,横竖屏,是否全
  9. [转载]系统内置的一些工具类
  10. 自定义RadioButton 文字在下,图片在上