Angularjs 如何在ng repeat中按orderby或其他筛选条件进行条件筛选?

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

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,因为它是一个数组

好的。经过一些澄清,让我们试一试。看到这个了吗

我使用两个不同的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
    }

  };
});