It seems angular doesn't do event delegation with repeaters. Someone opened an issue on github about it. The argument is if it actually leads to better performance.
There might be a workaround but it would require jQuery. It consists of creating a special directive to be used on a parent element and register the listener on its dom node.
Here's an example, that is passed a function name to be called when a children node is clicked, and is also passed a selector to help identify which children nodes to listen to.
Since angular's jquery implementation only gives us the bind
method - which is limited to registering event listeners to the actual element - we need to load jQuery to have access to either the on
or delegate
method.
HTML
<ul click-children='fun' selector='li'>
<li ng-repeat="s in ss" data-index="{{$index}}">{{s}}</li>
</ul>
The function defined is defined in the controller and it expects to be passed an index
$scope.fun = function(index){
console.log('hi from controller', index, $scope.ss[index]);
};
The directive uses $parse
to convert an expression into a function that will be called from the event listener.
app.directive('clickChildren', function($parse){
return {
restrict: 'A',
link: function(scope, element, attrs){
var selector = attrs.selector;
var fun = $parse(attrs.clickChildren);
element.on('click', selector, function(e){
// no need to create a jQuery object to get the attribute
var idx = e.target.getAttribute('data-index');
fun(scope)(idx);
});
}
};
});
Plunker: http://plnkr.co/edit/yWCLvRSLCeshuw4j58JV?p=preview
Note: Functions can be delegated to directives using isolate scopes {fun: '&'}
, which is worth a look, but this increases complexity.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…