【问题标题】:How to highlight a selected row in ngRepeat?如何突出显示 ngRepeat 中的选定行?
【发布时间】:2013-10-20 08:08:01
【问题描述】:

我找不到可以帮助我解决这个简单问题的方法 在角。比较时,所有答案都与导航栏相关 正在针对位置路径进行。

我已经使用列表和ngRepeat 构建了一个动态表。当我单击一行时,我试图为该行分配一个选定的 css 类,以突出显示该行已被用户选择的事实,并从先前突出显示的行中删除 .selected

我缺少在所选行和 css 类分配之间进行绑定的方法。

我申请了每个row (ul) ng-click="setSelected()" 但我缺少 function 中应用更改的逻辑。

My Code - Plunk

我的代码:

var webApp = angular.module('webApp', []);

//controllers
webApp.controller ('VotesCtrl', function ($scope, Votes) {
    $scope.votes  = Votes;
    $scope.statuses = ["Approved","Pending","Trash","Spam"];

    $scope.setSelected = function() {
       console.log("show");

    }
});

//services
webApp.factory('Votes', [function() {

    //temporary repository till integration with DB this will be translated into restful get query
    var votes = [
        {
            id: '1',
            created: 1381583344653,
            updated: '222212',
            ratingID: '3',
            rate: 5,
            ip: '198.168.0.0',
            status: 'Pending',
        },
        {
            id: '111',
            created: 1381583344653,
            updated: '222212',
            ratingID: '4',
            rate: 5,
            ip: '198.168.0.1',
            status: 'Spam'    

        },
        {
            id: '2',
            created: 1382387322693,
            updated: '222212',
            ratingID: '3',
            rate: 1,
            ip: '198.168.0.2',
            status: 'Approved'

        },
        {

            id: '4',
            created: 1382387322693,
            updated: '222212',
            ratingID: '3',
            rate: 1,
            ip: '198.168.0.3',
            status: 'Spam'
        }
    ];

    return votes;
}]);

我的 HTML:

  <body ng-controller='VotesCtrl'>
    <div>
    <ul>
        <li class="created">
            <a>CREATED</a>
        </li>
        <li class="ip">
            <b>IP ADDRESS</b>
        </li>
        <li class="status">
            <b>STATUS</b>
        </li>
    </ul>
    <ul ng-repeat="vote in votes" ng-click="setSelected()">
        <li  class="created">
          {{vote.created|date}}
        </li>
        <li class="ip">
            {{vote.ip}}
        </li>
        <li class="status">
            {{vote.status}}
        </li>
    </ul>
   </div>
   </body>

我的 CSS(仅选定的类):

.selected {
  background-color: red;
}

【问题讨论】:

    标签: angularjs angularjs-ng-repeat


    【解决方案1】:

    每一行都有一个 ID。您所要做的就是将此 ID 发送到函数 setSelected(),将其存储(例如在 $scope.idSelectedVote 中),然后检查每一行,如果所选 ID 与当前 ID 相同。这是一个解决方案(如果需要,请参阅 the documentation 获取 ngClass):

    $scope.idSelectedVote = null;
    $scope.setSelected = function (idSelectedVote) {
       $scope.idSelectedVote = idSelectedVote;
    };
    
    <ul ng-repeat="vote in votes" ng-click="setSelected(vote.id)" ng-class="{selected: vote.id === idSelectedVote}">
        ...
    </ul>
    

    Plunker

    【讨论】:

    • 这个解决方案 IMO 比以前的解决方案更好。
    • 有什么方法可以在不使用控制器的情况下做到这一点?我正在尝试在视图中找到一种“最佳”方法,但我没有运气。我尝试执行类似... ng-click="idSelectedVote = vote" ng-class="{selected:vote.id === idSelectedVote}" 但单击一行后,其他行仍处于选中状态。您的解决方案有效,但如果存在仅视图解决方案,那就太好了。
    • @Spencer 每个&lt;ul&gt; 都有一个由ngRepeat 创建的新范围;因此,ngClick 中的 idSelectedVote 仅修改本地范围,而不是与其他范围共享的范围。两种解决方案:改用$parent.idSelectedVote(真的很脏!),或者使用一个对象(&lt;ul&gt; 祖先中的ng-init="selectedVote = {id: null}")并且只修改它的一个属性,而不是整个对象(ng-click="selectedVote.id = vote.id")。无论如何,使用控制器总是是一个更好的解决方案
    • 自定义指令可能是将逻辑移出控制器的最佳方式,具体取决于您的应用程序的复杂程度和范围的拥挤程度。
    • @nikkwong 实际上,将逻辑放在控制器中通常是个好主意,除非您重复使用同一个,在这种情况下,指令确实非常适合。
    【解决方案2】:

    您可能希望 LI 而不是 UL 拥有背景色:

    .selected li {
      background-color: red;
    }
    

    那么你想为 UL 创建一个动态类:

    <ul ng-repeat="vote in votes" ng-click="setSelected()" class="{{selected}}">
    

    现在您需要在单击该行时更新 $scope.selected:

    $scope.setSelected = function() {
       console.log("show", arguments, this);
       this.selected = 'selected';
    }
    

    然后取消选择之前突出显示的行:

    $scope.setSelected = function() {
       // console.log("show", arguments, this);
       if ($scope.lastSelected) {
         $scope.lastSelected.selected = '';
       }
       this.selected = 'selected';
       $scope.lastSelected = this;
    }
    

    工作解决方案:

    http://plnkr.co/edit/wq6nxc?p=preview

    【讨论】:

    • 我点击了这个答案,因为我可以让它工作,但我无法让选中的那个继续下去。但是您在此处的代码和您的 plunker 中的代码之间存在一些差异。上面的 ng-click 缺少 (this),并且您上面的类在属性周围有引号,但 plunker 没有。
    • 在我发布 Plunker 链接后,我注意到它缺少引号,并且参数列表中的 this 仅由 console.log 使用。但是,您可以传入选定的行,或使用它,但不应使用 $scope,因为这是整个 VoteCtrl 的范围:plnkr.co/edit/JoSUwA?p=preview
    【解决方案3】:

    我需要类似的东西,能够点击一组图标来表示一个选择,或者一个基于文本的选择,并使用表示的值更新模型(2-way-binding)以及一种方式以指示哪个是视觉选择的。我为它created an AngularJS directive,因为它需要足够灵活,以处理任何被点击以指示选择的 HTML 元素。

    <ul ng-repeat="vote in votes" ...>
        <li data-choice="selected" data-value="vote.id">...</li>
    </ul>
    

    解决方案: http://jsfiddle.net/brandonmilleraz/5fr9V/

    【讨论】:

    • 请不要仅仅链接到外部网站、博客等,即使您是作者 - stackoverflow 上的一个很好的答案包含帖子本身的必要细节。
    猜你喜欢
    • 1970-01-01
    • 2017-03-15
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 2018-11-20
    • 2016-02-15
    • 1970-01-01
    • 2013-12-20
    相关资源
    最近更新 更多