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-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,因为它是一个数组。
答案 0 :(得分:1)
好。经过一番澄清后,让我们试一试。见working Plnkr
我使用两种不同的ng-repeats来匹配其中一种情况。
案例1“没有投票集”:
<!-- in case there is no vote -->
<div ng-if="main.office.vote == null">
No Vote set, show all candidates, orderedBy '-vScore'
<div ng-repeat="candidate in main.office.candidateProfiles | orderBy:'-vScore'">
{{candidate.fullName}}
</div>
</div>
案例2:“投票集”
<!-- in case there is a vote -->
<div ng-if="main.office.vote != null">
Vote set: only show candidates matching the office, orderedBy '-vScore'
<div ng-repeat="candidate in main.office.candidateProfiles | filter:main.isOfficeIdMatching | orderBy:'-vScore'">
{{candidate.fullName}}
</div>
</div>
过滤发生在一个小函数内:
vm.isOfficeIdMatching = function(candidate) {
return vm.office.vote.officeId == candidate.officeId;
}
我希望这是你一直在寻找的东西。一般来说,如果你能用最少的数据准备一个小的plnkr(就像我做的那样)以便更好地理解你的问题,那将是很好的。
一般情况下,我猜它可以进一步简化为只有一个ng-repeat并且具有首先检查的过滤器函数,如果设置了投票,并且 - 如果 - 它也调用isOfficeIdMatching
函数。 / p>
修改强> 检查两种情况的结果,删除JSON对象内的投票对象。 请参阅app.js中的LoC 36-38
//remove the vote object, to see another output.
vote: {
officeId: 8
}
编辑2: 要获得简化的解决方案:Simplified Plnkr(没有ng-if由于OP的评论)
没有ng-if了。并且isVoteSet
函数负责检查officeId是否匹配。如果没有设置投票,则只返回true。
<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;
}
编辑3:
因为您的用例如下。
A)如果设置了投票,请过滤所有候选列表以匹配已投票的那个
B)如果未设置投票,只需按vScore订购列表
这是您问题的最终解决方案:Final Plnkr
HTML
<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>
JS
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
}
};
});