什么元素在自定义指令ng-repeat中引发了ng-click

时间:2013-10-17 14:11:59

标签: javascript jquery angularjs angularjs-directive angularjs-ng-click

我在指令中有一个转发器,它会吐出表行。

当用户点击某行时,我想突出显示该行。

我有一些有用的东西,我只是想知道是否有更好的方法:

.directive('userList', function(){
    return{
        restrict: 'A',
        template: '<table>'+
                    '<tr>'+
                        '<th>User Name</th>'+
                        '<th>First Name</th>'+
                        '<th>Last Name</th>'+
                        '<th>Email Address</th>'+
                    '</tr>'+
                    '<tr ng-repeat="user in users" ng-click="selectUser(user,$event)" ng-mouseenter="overUser($event)" ng-mouseleave="leaveUser($event)">'+
                        '<td ng-click="selectUser(user)">{{user.UserName}}</td>'+
                        '<td>{{user.FirstName}}</td>'+
                        '<td>{{user.LastName}}</td>'+
                        '<td>{{user.Email}}</td>'+
                    '</tr>'+
                '</table>',
        scope:{
                selectedUser: '=',
                users: '='
        },
        link: function (scope, elem, attrs){
            scope.selectUser = function(user,event){
                $("div[user-list] tr.ts-li-selected").removeClass("ts-li-selected");
                $(event.target).closest("tr").addClass("ts-li-selected");
                scope.selectedUser=user;
            };
            scope.overUser = function(event){
                $("div[user-list] tr.ts-li-over").removeClass("ts-li-over");
                $(event.target).closest("tr").addClass("ts-li-over");
            };
            scope.leaveUser = function(event){
                $("div[user-list] tr.ts-li-over").removeClass("ts-li-over");
            };
        }
    }
});

我注意到this似乎没有引用引发事件的元素,就像我在直接java或jQuery中完成它一样。而不是那样,我已经将事件发送到我的函数,event.target总是发送子进程,所以我去表行来设置行上的类。

我想知道是否有一种更清晰的方法,如果实际上有一个“this”引用,角度将在这些情况下使用,我可以调用而不是走DOM树。

3 个答案:

答案 0 :(得分:3)

您可以使用ng-class指令将特殊类添加到单击的<tr>。只需看一下您的代码,就会在点击任何scope.selectedUser时设置<tr>。所以你应该能够做到以下几点:

在你的模板中:

...
'<tr ng-repeat="user in users" ng-click="selectUser(user)" ng-class="{'ts-li-selected': selectedUser.id == user.id}">'+
    '<td ng-click="selectUser(user)">{{user.UserName}}</td>'+
    '<td>{{user.FirstName}}</td>'+
    '<td>{{user.LastName}}</td>'+
    '<td>{{user.Email}}</td>'+
'</tr>'+
...

只要ng-class的ID与该行的ts-li-selected匹配,<tr>会自动将$scope.selectedUser课程应用于user.id,并会删除该课程如果那个条件不再有效。

然后您的$scope.selectUser()功能可以简化为:

scope.selectUser = function(user){
    scope.selectedUser = user;
};

希望有所帮助。

PS。至于您的mouseovermouseleave类,您是否只能在css样式表中添加以下内容?

tr:hover{ /* special styles here */ }
tr.ts-li-selected:hover{ /* don't do special styles here */ }

答案 1 :(得分:1)

工作小提琴:http://jsfiddle.net/strajk/XAFmb/

你可以简化为类似的东西

<tr
    ng-repeat="user in users"
    ng-click="selectUser(user)"
    ng-mouseenter="hoverUser(user)"
    ng-class="{
        'ts-li-selected': selectedUser.id == user.id,
        'ts-li-hovered': hoveredUser.id == user.id   
    }"
>

并指示这样的事情:

.directive('userList', function(){
    return{
        restrict: 'A',
        templateUrl: 'userList.html' ,
        scope: {
                users: '='
        },
        controller: function($scope) {
            $scope.selectedUser = null;
            $scope.hoveredUser = null;

            $scope.selectUser = function(user) {
                $scope.selectedUser = user;
            }
            $scope.hoverUser = function(user) {
                $scope.hoveredUser = user;
            }

        }
    }
});

答案 2 :(得分:0)

参数'elem'得到了指令设置的JQuery元素。