AngularJS - 基于父 ng-repeat 排序和解析 ng-repeat 中的数据 [英] AngularJS - Ordering and Parsing data in a ng-repeat, based on a parent ng-repeat

查看:25
本文介绍了AngularJS - 基于父 ng-repeat 排序和解析 ng-repeat 中的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个相当复杂的 ng-repeat,它可能会使用过滤和解析.

我首先要做的是 ng-repeat 从当前月份开始 12 个月的表格标题.

然后我将显示两行 - 有影响的搜索没有影响的搜索

我想要做的是遍历包含我的搜索数据的 JSON 文件,并计算有多少有影响的搜索无影响的搜索根据 SearchedOn 字段针对该特定月份执行.

理解有影响的搜索无影响的搜索背后的逻辑是基于IsIncludedInSearchImpactCalculation字段是真还是假.

还需要发生的是,如果我的 JSON 文件包含超过 12 个月的数据元素(基于 SearchedOn 字段),则不应将其包含在计算中.

HTML:

<div ng-controller="Ctrl"><表格><头><tr><th></th><th ng-repeat="currMonth in Month">{{currMonth}}</th></tr></thead><tr><th>具有影响力的搜索</th><td></td><td>3</td><td></td><td>1</td><td>1</td><td></td><td></td><td></td><td></td><td>3</td><td>1</td><td></td><td>1</td></tr><tr><th>没有影响的搜索</th><td>2</td><td></td><td></td><td></td><td></td><td>1</td><td></td><td></td><td></td><td></td><td></td><td></td></tr></tbody><br><p>具有影响力的搜索:</p><li ng-repeat="searchedOn in Searches | filter:{IsIncludedInSearchImpactCalculation:true}">{{searchedOn.SearchedOn}}</li><br><p>没有影响的搜索:</p><li ng-repeat="searchedOn in Searches | filter:{IsIncludedInSearchImpactCalculation:false}">{{searchedOn.SearchedOn}}</li>

JS:

angular.module('test', []).controller('Ctrl', function ($scope) {var date = new Date();var 月 = [],月份名称 = [一月",二月",三月",四月",五月",六月",七月"、八月"、九月"、十月"、十一月"、十二月"];for (var i = 0; i <12; i++) {月.push(月名[date.getMonth()] + ' ' + date.getFullYear());//每次减去一个月date.setMonth(date.getMonth() - 1);}$scope.months = 月;$scope.Searches = [{"SearchedOn": "19/04/2014",IsIncludedInSearchImpactCalculation":true}, {"SearchedOn": "18/04/2014",IsIncludedInSearchImpactCalculation":true}, {"SearchedOn": "01/05/2014",IsIncludedInSearchImpactCalculation":false}, {"SearchedOn": "21/05/2014",IsIncludedInSearchImpactCalculation":false}, {"SearchedOn": "20/07/2013",IsIncludedInSearchImpactCalculation":true}, {"SearchedOn": "07/01/2014",IsIncludedInSearchImpactCalculation":true}, {"SearchedOn": "08/12/2013",IsIncludedInSearchImpactCalculation":false}, {"SearchedOn": "24/02/2014",IsIncludedInSearchImpactCalculation":true}, {"SearchedOn": "30/06/2013",IsIncludedInSearchImpactCalculation":true}, {"SearchedOn": "28/06/2014",IsIncludedInSearchImpactCalculation":true}, {"SearchedOn": "14/08/2013",IsIncludedInSearchImpactCalculation":true}, {"SearchedOn": "11/04/2014",IsIncludedInSearchImpactCalculation":true}, {"SearchedOn": "13/08/2013",IsIncludedInSearchImpactCalculation":true}, {"SearchedOn": "03/08/2013",IsIncludedInSearchImpactCalculation":true}, {"SearchedOn": "20/01/2011",IsIncludedInSearchImpactCalculation":true}];});

这是我的小提琴:http://jsfiddle.net/oampz/j9LBe/

在我的小提琴中,我根据列表手动硬编码了表格的外观.

<小时>

更新:

添加:

<td ng-repeat="过滤中的项目 = (搜索 | 过滤器:{IsIncludedInSearchImpactCalculation:true})"></td><td>过滤后的列表有 {{filtered.length}} 个项目</td>

获取有影响的搜索无影响的搜索的连续项目总数,请参阅fiddle:http://jsfiddle.net/oampz/j9LBe/1/

现在所需要做的就是根据之前的 ng-repeat 按月分组:

 

解决方案

Fiddle Here

归结为这个过滤器:

$scope.searchFilter = function(included,date){返回函数(搜索){if(search.IsIncludedInSearchImpactCalculation!==included) return false;//需要在json的日期上解析和使用日期构造函数var dateParts = search.SearchedOn.split("/");var searchedOn = new Date(dateParts[2],dateParts[1]-1,dateParts[0]);//月份是0-11if(date.month === searchedOn.getMonth() && date.year===searchedOn.getFullYear()) 返回真;否则返回假;};}

并像这样使用它:

有影响的搜索;<td ng-repeat="currMonth in Month">{{(Searches|filter:searchFilter(true,currMonth)).length}}</td>

或者这个:

没有影响的搜索;<td ng-repeat="currMonth in Months">{{(Searches|filter:searchFilter(false,currMonth)).length}}</td>

这基本上完成了标题中的要求,基于父循环(ng-repeat 几个月)解析和过滤内部循环中的数据(由 | filter 将数组的每个元素传递给一个函数.)

基本上我们需要再次ng-repeat 个月,但这次是为了打印每个月包含和不包含搜索的计数.所以我们的过滤器需要 3 个参数,首先是是否包含它,其次是有问题的月份,最后是用于检查匹配月份的搜索.

角度过滤器需要一个数组来过滤并将每个项目传递给过滤器函数.因此,我们返回一个函数,该函数将单个搜索作为参数,执行我们的操作并根据它是否符合我们的条件返回 true 或 false.

结果<代码>|filter 返回一个新数组,其中填充了过滤器函数返回的真值(这样我们可以使用过滤器等ng-repeat).由于我们现在有了匹配的数组,我们可以简单地将其长度作为计数.

我知道这听起来有点令人困惑,但检查小提琴它并不像我解释的那样令人困惑.

有什么不清楚的可以问.

Im trying to write a fairly complex ng-repeat that potentially uses filtering and parseing.

What i am first doing is ng-repeating a table heading of 12 months from the current month.

I am then displaying two rows - Searches with impact and Searches with NO impact

What i am trying to do is loop through my JSON file that contains my search data, and counts how many Searches with Impact and Search with No Impact, have been carried out for that particular month based on the SearchedOn field.

The logic behind understanding Searches with Impact and Search with No Impact is based on the IsIncludedInSearchImpactCalculation field being true or false.

What also needs to happen is that if my JSON file contains element of data that is greater than 12months old (based on the SearchedOn field), then this should be not included in the calculation.

HTML:

<div ng-app="test">
    <div ng-controller="Ctrl">
        <table>
            <thead>
                <tr>
                    <th></th>
                    <th ng-repeat="currMonth in months">{{currMonth}}</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <th>Searches with impact</th>
                    <td></td>
                    <td>3</td>
                    <td></td>
                    <td>1</td>
                    <td>1</td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td>3</td>
                    <td>1</td>
                    <td></td>
                    <td>1</td>
                </tr>
                <tr>
                    <th>Searches with NO impact</th>
                    <td>2</td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td>1</td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
            </tbody>
        </table>
        <br>
        <p>Searches with impact:</p>
        <li ng-repeat="searchedOn in Searches | filter:{IsIncludedInSearchImpactCalculation:true}">{{searchedOn.SearchedOn}}</li>
        <br>
        <p>Searches with NO impact:</p>
        <li ng-repeat="searchedOn in Searches | filter:{IsIncludedInSearchImpactCalculation:false}">{{searchedOn.SearchedOn}}</li>
    </div>
</div>

JS:

angular.module('test', []).controller('Ctrl', function ($scope) {
    var date = new Date();
    var months = [],
        monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
    for (var i = 0; i < 12; i++) {
        months.push(monthNames[date.getMonth()] + ' ' + date.getFullYear());

        // Subtract a month each time
        date.setMonth(date.getMonth() - 1);
    }
    $scope.months = months;



    $scope.Searches = [{
        "SearchedOn": "19/04/2014",
            "IsIncludedInSearchImpactCalculation": true
    }, {
        "SearchedOn": "18/04/2014",
            "IsIncludedInSearchImpactCalculation": true
    }, {
        "SearchedOn": "01/05/2014",
            "IsIncludedInSearchImpactCalculation": false
    }, {
        "SearchedOn": "21/05/2014",
            "IsIncludedInSearchImpactCalculation": false
    }, {
        "SearchedOn": "20/07/2013",
            "IsIncludedInSearchImpactCalculation": true
    }, {
        "SearchedOn": "07/01/2014",
            "IsIncludedInSearchImpactCalculation": true
    }, {
        "SearchedOn": "08/12/2013",
            "IsIncludedInSearchImpactCalculation": false
    }, {
        "SearchedOn": "24/02/2014",
            "IsIncludedInSearchImpactCalculation": true
    }, {
        "SearchedOn": "30/06/2013",
            "IsIncludedInSearchImpactCalculation": true
    }, {
        "SearchedOn": "28/06/2014",
            "IsIncludedInSearchImpactCalculation": true
    }, {
        "SearchedOn": "14/08/2013",
            "IsIncludedInSearchImpactCalculation": true
    }, {
        "SearchedOn": "11/04/2014",
            "IsIncludedInSearchImpactCalculation": true
    }, {
        "SearchedOn": "13/08/2013",
            "IsIncludedInSearchImpactCalculation": true
    }, {
        "SearchedOn": "03/08/2013",
            "IsIncludedInSearchImpactCalculation": true
    }, {
        "SearchedOn": "20/01/2011",
            "IsIncludedInSearchImpactCalculation": true
    }];
});

Here's my fiddle: http://jsfiddle.net/oampz/j9LBe/

In my fiddle, i have manually hard coded what the table should look like based on the lists.


UPDATE:

Adding:

<td ng-repeat="item in filtered = (Searches | filter:{IsIncludedInSearchImpactCalculation:true})"></td>
                <td>Filtered list has {{filtered.length}} items</td>

Gets me the total number of items in a row for Searches with impact or Searches with NO impact see fiddle: http://jsfiddle.net/oampz/j9LBe/1/

Now all that is needed is to group by month based on the previous ng-repeat:

 <th ng-repeat="currMonth in months">{{currMonth}}</th>

解决方案

Fiddle Here

It simply boils down to this filter:

$scope.searchFilter = function(included,date){
    return function(search){
        if(search.IsIncludedInSearchImpactCalculation!==included) return false;

        //needed to parse and use date constructor on your json's dates
        var dateParts = search.SearchedOn.split("/");
        var searchedOn = new Date(dateParts[2],dateParts[1]-1,dateParts[0]);//months are 0-11

        if(date.month === searchedOn.getMonth() && date.year===searchedOn.getFullYear()) return true;
        else return false;
    };
}

and used it like this:

<th>Searches with impact</th>
      <td ng-repeat="currMonth in months">{{(Searches|filter:searchFilter(true,currMonth)).length}}</td>

or this:

<th>Searches with NO impact</th>
      <td ng-repeat="currMonth in months">{{(Searches|filter:searchFilter(false,currMonth)).length}}</td>

This basically does what you are asking in the title, based on the parent loop (ng-repeat of months) parses and filters data in inner loop(which is caused by | filter passing every element of array to a function.)

Basically we need to ng-repeat months again but this time for printing count of included and not included searches for each month. So our filter needs 3 parameters, first whether it's included or not, second the month in question and lastly the searches to check for matching months.

angular filters expect an array to filter and passes each item to the filter function. So we return a function that gets single search as a parameter, do our thing and return true or false depending on if it's matched our criteria or not.

As a result | filter returns a new array filled with ones returned true from the filter function(this way we can ng-repeat with filters etc). Since we have our matched array now, we can simply get it's length as count.

I know sounds kind of confusing but check the fiddle it's not as confusing as i explained.

Feel free to ask anything that is not clear.

这篇关于AngularJS - 基于父 ng-repeat 排序和解析 ng-repeat 中的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆