我试图在数据表中设置一个简单的突出显示机制:
<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>
我有一个处理突出显示的指令。您点击<tr>
,它会尝试首先取消突出显示所有其他<tr>
,然后突出显示所点击的directive('highlightable', function() {
return {
require: 'highlightable',
controller: function($scope, $element) {
this.unhighlight = function(file) {
$element[0].style.backgroundColor = 'transparent';
};
},
link: function(scope, element, attrs, ctrl) {
var color = '#DEE4FC';
element.bind('click', function(e) {
ctrl.unhighlight(scope.file);
element[0].style.backgroundColor = color;
});
}
};
});
。
ng-repeat
问题是它似乎没有访问指令控制器的每个实例。当需要另一个指令时,如何确保我在{{1}}场景中需要该指令的每个实例,并通过每个重复指令的控制器方法操作每个实例?
答案 0 :(得分:1)
考虑到你想要实现的目标,我会这样做。基本上使用范围通知来在元素之间进行通信。
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;
});
}
};
});
演示:link
<强>更新强>
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;
});
}
};
});
演示:link
答案 1 :(得分:1)
[@buu Nyuyen]的应用问题是他错过了处理范围的一些逻辑。如果您有另一个由指令highlightable
修改的列表,则如果从第一个列表广播该事件并使该指令不可重用,则第二个列表将受到影响。你可以在这里看到这个问题。 的 Issue 强>
但是,您可以通过循环浏览其他元素轻松实现它。诀窍是你可以用element[0].parentElement.children
获得所有重复的元素。
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;
});
}
};
});
的 Working Demo 强>
答案 2 :(得分:0)
最简单的解决方案是Buu Nguyen提出的解决方案,我提供了一个更难的解决方案。
解决此问题的一种典型方法是拥有一个父指令,该指令将了解每个孩子。因此,您可以在每一行注册,当您点击一行时,父母将取消其他孩子的注意。
更复杂但更易于配置。您可以创建名为... multi
的属性,以便能够突出显示多个属性。或者甚至可以选择最多x
行......你想要什么。
如果你很好奇,我会在这里留下你的演示:http://jsfiddle.net/5NSW3/1/