Angularjs 如何在ng repeat中按orderby或其他筛选条件进行条件筛选?
TLDR:我试图实现的目标:如果存在office.vote(如果存在),则按office.vote.candidateId进行筛选。否则,按office.candiateProfiles.vScore订购Angularjs 如何在ng repeat中按orderby或其他筛选条件进行条件筛选?,angularjs,angularjs-ng-repeat,angularjs-filter,Angularjs,Angularjs Ng Repeat,Angularjs Filter,TLDR:我试图实现的目标:如果存在office.vote(如果存在),则按office.vote.candidateId进行筛选。否则,按office.candiateProfiles.vScore订购 .offices(ng-repeat='office in service.offices' ng-class="{'last':$last}") .row.row-format.text-uppercase .office.ballot(ng-cl
.offices(ng-repeat='office in service.offices' ng-class="{'last':$last}")
.row.row-format.text-uppercase
.office.ballot(ng-click='showCandidates = !showCandidates')
.col-xs-7.col-sm-4.col-md-4.mainBallot-col
.office-name
{{office.name}}
.col-xs-5.col-sm-8.col-md-8.border-left.mainBallot-col
.ballot(ng-repeat="candidate in office.candidateProfiles | orderBy: '-vScore' | filter: office.vote.candidateId | limitTo: 1 | " )
.row.noPad
.col-xs-1.col-sm-1.col-md-1.straight-col.ballotCheck-col
.col-xs-7.col-sm-7.col-md-7.straight-col.highest-col
%table.highestShow
%tr
%td
.vs
{{candidate.fullName}}
我意识到我试图将上面的orderby和filter结合起来是行不通的。我对自定义过滤器不是非常熟悉。如何使用自定义过滤器实现我的目标 我认为我的问题在于candiateProfiles是一个数组 以下是作用域中的对象:
尝试2失败:
.ballot(ng-repeat="candidate in office.candidateProfiles | filter:criteriaMatch(office) | limitTo:1" )
控制器:
$scope.criteriaMatch = function(office) {
console.log(office);
if (office.vote) {
return office.vote.candidateId;
} else {
return orderBy(office.candidateProfiles.vScore)
}
};
在上面的控制器中,这适用于按office.vote进行过滤,但我需要一种新的方式让“else”按最高的vScore进行过滤。我认为它不能识别candiateProfiles,因为它是一个数组 好的。经过一些澄清,让我们试一试。看到这个了吗 我使用两个不同的ng重复来匹配一个或另一个情况 案例1“否决票集”: 我希望这就是你一直在寻找的。总的来说,如果你能用最少的数据准备一个小的plnkr(就像我做的那样)来更好地理解你的问题,那就太好了 一般来说,我想它可以进一步简化为只有一个ng repeat,并且有一个过滤函数,首先检查是否设置了投票,如果-它也调用
isoficeidmatching
函数
编辑:
要检查这两种情况的结果,请删除JSON对象中的投票对象。
见app.js中的LoC 36-38
//remove the vote object, to see another output.
vote: {
officeId: 8
}
编辑2:
要获得简化的解决方案:(如果由于OP的评论,则无ng)
再也没有ng if了。而isVoteSet
函数负责检查officeId是否匹配。如果未设置投票,则返回true
<div ng-repeat="candidate in main.office.candidateProfiles | filter:main.isVoteSet | orderBy:'-vScore'">
{{candidate.fullName}}
</div>
编辑3:
您的用例如下所示
A) 如果设置了投票,则筛选所有候选资格文件以匹配已投票的候选人
B) 如果未设置投票,只需按vScore对列表排序即可
以下是您问题的最终解决方案:
HTML
我对这个问题不是很清楚。你能试着更具体地描述你的逻辑吗?或者更好:为此创建一个小plnkr?Tamplte对于Angular 1.4,我试图澄清我试图实现的目标。@limgb,这更清楚吗?是的。但是:不清楚为什么要在一个案例上进行筛选,而在另一个案例上只筛选orderBy。是否有触发筛选的输入?是否有创建office.vote的复选框。在单击糖果旁边的框之前,它不存在。在它被创建之前,我想根据分数显示最高的结果。创建后,所选候选人(office.vote.candidateId)将按分数替换默认筛选。这与我之前提出的方法类似,使用2个ng ifs,我同意必须为该(DRY)提供一个简化筛选,这就是我正在尝试解决的问题。在上面的条件中,我不知道如何按office.candidateProfiles.vScore进行筛选/排序,我肯定我缺少了一些东西。
vm.isOfficeIdMatching = function(candidate) {
return vm.office.vote.officeId == candidate.officeId;
}
//remove the vote object, to see another output.
vote: {
officeId: 8
}
<div ng-repeat="candidate in main.office.candidateProfiles | filter:main.isVoteSet | orderBy:'-vScore'">
{{candidate.fullName}}
</div>
vm.isVoteSet = function(candidate) {
if(vm.office.vote != null) {
return vm.isOfficeIdMatching(candidate);
}
return true;
}
<div ng-repeat="candidate in main.office.candidateProfiles| filter:main.isVoteSet | orderBy:main.whichOrderByPredicate">
<label>
<input type="checkbox" ng-click="main.setVote(candidate)"/>
{{candidate.fullName}}
</label>
</div>
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
var vm = this;
vm.office = {
name: "Metro Mayer",
candidateProfiles: [
{
candidateId: 5,
fullName: "John (Id 15, Score 1)",
vScore: 1
},
{
candidateId: 8,
fullName: "Linda (Id 8, Score 3)",
vScore: 3
},
{
candidateId: 120,
fullName: "Ben (Id 120, Score 2)",
vScore: 2
},
{
candidateId: 14,
fullName: "Rick (Id 14, Score 1)",
vScore: 1
},
{
candidateId: 15,
fullName: "Tesla (Id 15, Score 2)",
vScore: 2
}
],
vote: {}
};
/*Filtering functions
only used if a vote is set
*/
vm.isVoteSet = function(candidate) {
if(JSON.stringify(vm.office.vote) != "{}") {
return vm.isCandidateIdMatching(candidate);
}
return true;
};
vm.isCandidateIdMatching = function(candidate) {
return vm.office.vote.candidateId == candidate.candidateId;
};
/*Ordering functions
only used if NO vote is set
*/
vm.whichOrderByPredicate = function(candidate) {
return JSON.stringify(vm.office.vote) == "{}" ? -candidate.vScore : null;
};
/* Application logic */
vm.setVote = function(candidate) {
//unset if already set
if(vm.office.vote.candidateId == candidate.candidateId) {
vm.office.vote = {};
}
//else set the vote
else {
vm.office.vote.candidateId = candidate.candidateId
}
};
});