Angularjs 指令的所有重复实例上的内部指令通信

Angularjs 指令的所有重复实例上的内部指令通信,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我试图在数据表中设置一个简单的突出显示机制: <table> <thead> <tr> <th>Name</th> <th>Owner</th> </tr> </thead> <tbody> <tr ng-repeat="file in files" h

我试图在数据表中设置一个简单的突出显示机制:

<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Owner</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="file in files" highlightable> <!-- Multiple instances of highlightable -->
            <td>{{file.name}}</td>
            <td>{{file.owner}}</td>
        </tr>
    </tbody>
</table>
问题是,它似乎并没有访问指令控制器的每个实例。当需要另一个指令时,如何确保在ng repeat场景中需要该指令的每个实例,并通过每个repeat指令的控制器方法操纵每个实例


考虑到你想要达到的目标,我会这么做。基本上使用范围通知在元素之间进行通信

directive('highlightable', function() {
    return {
        link: function(scope, element, attrs) {
            var color = '#DEE4FC';
            scope.$on("reset", function() {
                element[0].style.backgroundColor = 'transparent';
            });
            element.bind('click', function(e) {
                scope.$parent.$broadcast("reset");
                element[0].style.backgroundColor = color;
            });
        }
    };
});
演示:

更新 sze正确地指出,我的解决方案只适用于您需要恰好一个列表的情况。但是,在保持代码简洁性的同时,很容易容纳多个列表

<tr ng-repeat="file in files" highlightable="list1">
    <td>{{file.name}}</td>
    <td>{{file.owner}}</td>
</tr>

...

<tr ng-repeat="file in files" highlightable="list2">
    <td>{{file.name}}</td>
    <td>{{file.owner}}</td>
</tr>

...

directive('highlightable', function () {
    return {
        link: function (scope, element, attrs) {
            var color = '#DEE4FC';
            scope.$on(attrs.highlightable, function () {
                element[0].style.backgroundColor = 'transparent';
            });
            element.bind('click', function (e) {
                scope.$parent.$broadcast(attrs.highlightable);
                element[0].style.backgroundColor = color;
            });
        }
    };
});

演示:

最简单的解决方案是Buu Nguyen提出的,我提供了一个更难的解决方案

解决这个问题的一个典型方法是制定一个家长指令,让每个孩子都知道。因此,您可以在那里注册每一行,当您单击其中一行时,父行将取消高亮显示其他子行

更复杂但更可配置。您可以创建一个名为。。。“多个”可以突出显示多个。甚至可以选择最多x行。。。你想要什么


如果你好奇的话,我在这里给你留个演示:

关于[@buu Nyuyen]的解释的问题是他错过了一些处理范围的逻辑。如果指令highlightable修改了另一个列表,则如果从第一个列表广播事件并使指令不可重用,则第二个列表将受到影响。你可以在这里看到这个问题

但是,您可以通过循环其他元素轻松实现它。诀窍是可以使用元素[0].parentElement.children获取所有重复的元素

<tr ng-repeat="file in files" highlightable="list1">
    <td>{{file.name}}</td>
    <td>{{file.owner}}</td>
</tr>

...

<tr ng-repeat="file in files" highlightable="list2">
    <td>{{file.name}}</td>
    <td>{{file.owner}}</td>
</tr>

...

directive('highlightable', function () {
    return {
        link: function (scope, element, attrs) {
            var color = '#DEE4FC';
            scope.$on(attrs.highlightable, function () {
                element[0].style.backgroundColor = 'transparent';
            });
            element.bind('click', function (e) {
                scope.$parent.$broadcast(attrs.highlightable);
                element[0].style.backgroundColor = color;
            });
        }
    };
});
directive('highlightable', function () {
    return {
        require: 'highlightable',
        controller: function ($scope, $element) {
            this.unhighlight = function (element) {
                element.style.backgroundColor = 'transparent';
            };
        },
        link: function (scope, element, attrs, ctrl) {
            var color = '#DEE4FC';
            element.bind('click', function (e) {
                angular.forEach(element[0].parentElement.children, function (element) {
                    ctrl.unhighlight(element);
                })
                element[0].style.backgroundColor = color;
            });
        }
    };
});