我试图编写一个相当复杂的ng-repeat
,可能会使用过滤和解析。
我首先要做的是ng-repeat
从当月起12个月的表格。
然后我显示两行 - 有影响力的搜索和没有影响的搜索
我要做的是循环浏览包含我的搜索数据的JSON文件,并计算有多少带有影响的搜索和无影响搜索的数量根据 SearchedOn 字段为该特定月份执行。
理解具有影响力的搜索和无影响搜索背后的逻辑基于 IsIncludedInSearchImpactCalculation 字段为true或false。
还需要发生的是,如果我的JSON文件包含大于12个月的数据元素(基于 SearchedOn 字段),那么这应该不包括在计算中。 / p>
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
}];
});
这是我的小提琴:http://jsfiddle.net/oampz/j9LBe/
在我的小提琴中,我根据列表手动硬编码了表格的样子。
更新
添加:
<td ng-repeat="item in filtered = (Searches | filter:{IsIncludedInSearchImpactCalculation:true})"></td>
<td>Filtered list has {{filtered.length}} items</td>
获取带有影响的搜索或无影响的搜索的行中的项目总数,请参阅小提琴:http://jsfiddle.net/oampz/j9LBe/1/
现在所需要的只是根据之前的ng-repeat分组:
<th ng-repeat="currMonth in months">{{currMonth}}</th>
答案 0 :(得分:1)
试试这个
<强>脚本强>
<强> Working Demo 强>
var months = [],
monthNames = [{ monthNo: 1, monthName: "Jan" },
{ monthNo: 2, monthName: "Feb" },
{ monthNo: 3, monthName: "Mar" },
{ monthNo: 4, monthName: "Apr" },
{ monthNo: 5, monthName: "May" },
{ monthNo: 6, monthName: "Jun" },
{ monthNo: 7, monthName: "Jul" },
{ monthNo: 8, monthName: "Aug" },
{ monthNo: 9, monthName: "Sep" },
{ monthNo: 10, monthName: "Oct" },
{ monthNo: 11, monthName: "Nov" },
{ monthNo: 12, monthName: "Dec" }];
for (var i = 0; i < 12; i++) {
var obj = {};
obj.month = monthNames[date.getMonth()];
obj.year = date.getFullYear();
months.push(obj);
// Subtract a month each time
date.setMonth(date.getMonth() - 1);
}
<强> HTML 强>
<th ng-repeat="curr in months|orderBy:'month.monthNo'">{{curr.month.monthName}} {{curr.year}}</th>
答案 1 :(得分:1)
<强> Fiddle Here 强>
它简单地归结为这个过滤器:
$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;
};
}
并像这样使用它:
<th>Searches with impact</th>
<td ng-repeat="currMonth in months">{{(Searches|filter:searchFilter(true,currMonth)).length}}</td>
或者这个:
<th>Searches with NO impact</th>
<td ng-repeat="currMonth in months">{{(Searches|filter:searchFilter(false,currMonth)).length}}</td>
这基本上是你在标题中提出的,基于父循环(ng-repeat
月)解析和过滤内循环中的数据(由| filter
传递每个数组元素到函数。)
基本上我们需要再次ng-repeat
个月,但这次是为每个月打印已包含和未包含的搜索计数。所以我们的过滤器需要3个参数,首先是它是否包括在内,第二个是有问题的月份,最后是检查匹配月份的搜索。
angular filters希望数组过滤并将每个项目传递给过滤器函数。所以我们返回一个函数,将单个搜索作为参数,做我们的事情并返回true或false,具体取决于它是否符合我们的标准。
结果| filter
返回一个新数组,其中填充了一些从过滤函数返回true的数组(这样我们就可以ng-repeat
使用过滤器等)。由于我们现在有匹配的数组,我们可以简单地计算它的长度。
我知道这听起来有些令人困惑,但要检查一下它并不像我解释的那样令人困惑。
随意提出任何不清楚的事情。
答案 2 :(得分:1)
<强> Working Demo - JSFiddle 强>
<强>脚本:强>
检索过去12个月并将其存储在数组中。请注意,我们存储了一个对象文字数组(年,月,值)。
function getMonths() {
var date = new Date();
var months = [];
for (var i = 0; i < 12; i++) {
months.push({
year: date.getFullYear(),
month: date.getMonth()+1,
value: new Date(date.getFullYear(), date.getMonth(), 1)
});
// Subtract a month each time
date.setMonth(date.getMonth() - 1);
}
return months;
}
$scope.months = getMonths();
定义搜索过滤器。这些搜索过滤器将用于按搜索影响缩小搜索结果范围,并按月对结果进行分组。 'count'过滤器是返回结果计数的最终过滤器。
按搜索影响过滤:
app.filter('bySearchImpact', function() {
return function(input, isIncludedInSearchImpact) {
var output = [];
for (var i in input) {
if (input[i].IsIncludedInSearchImpactCalculation == isIncludedInSearchImpact) {
output.push(input[i]);
}
}
return output;
}
});
按月过滤:
app.filter('byMonth', function () {
function isSameMonth(date1, date2) {
var month1 = date1.split('/')[1];
var year1 = date1.split('/')[2];
return parseInt(year1) == date2.year &&
parseInt(month1) == date2.month;
}
return function (input, month) {
var output = [];
for (var i in input) {
if (isSameMonth(input[i].SearchedOn, month)) {
output.push(input[i]);
}
}
return output;
};
});
计数过滤器:
app.filter('count', function() {
return function(input) {
return input.length;
};
});
<强> HTML:强>
现在我们有了SearchImpact和Month过滤的过滤器,以及用于返回计数的过滤器,我们可以应用它们来获得最终结果:
显示表标题(注意我们如何使用Angular的日期过滤器)
<th ng-repeat="month in months">{{month.value | date: 'MMM yyyy' }}</th>
使用影响进行搜索:
<td ng-repeat="month in months">{{Searches | bySearchImpact:true | byMonth:month | count}}</td>
没有影响的搜索:
<td ng-repeat="month in months">{{Searches | bySearchImpact:false | byMonth:month | count }}</td>
显示具有影响力的搜索日期:
<li ng-repeat="searchedOn in Searches | bySearchImpact:true">{{searchedOn.SearchedOn}}</li>
显示没有影响的搜索日期:
<li ng-repeat="searchedOn in Searches | bySearchImpact:false">{{searchedOn.SearchedOn}}</li>