这是一个指令,我试图根据模型值禁用链接:
app.directive('disableable', function($parse){
return {
restrict: 'C',
require: '?ngClick',
link: function (scope, elem, attrs, ngClick) {
if (attrs.disable){
var disable = $parse(attrs.disable);
elem.bind('click', function (e) {
if (disable(scope)){
e.preventDefault();
return false;
}
return true;
});
scope.$watch(disable, function (val) {
if (val){
elem.addClass('disabled');
elem.css('cursor', 'default');
}
else {
elem.removeClass('disabled');
elem.css('cursor', 'pointer');
}
});
}
}
};
});
我希望能够禁用所有链接操作,无论他们是使用简单的href还是ngClick操作。由于preventDefault调用,Hrefs工作正常,但我无法弄清楚如何深入了解ngClick并防止它被触发。我在click事件上执行的绑定不起作用,因为看起来ngClick绑定了我自己无法控制的处理程序。我有什么可以做的吗?
jsFiddle:http://jsfiddle.net/KQQD2/2/
答案 0 :(得分:8)
使用event.stopImmediatePropagation
。
来自MDN:
如果多个侦听器连接到同一个元素 事件类型,按照添加它们的顺序调用它们。如果 在一次这样的调用中,调用event.stopImmediatePropagation(),no 剩下的听众将被召集。
...
elem.bind('click', function (e) {
if (disable(scope)){
e.stopImmediatePropagation();
return false;
}
return true;
});
...
答案 1 :(得分:4)
您只需将ng-click更改为disableIt || tellAboutIt()
即可按原样运行。例如
<a class="disableable" target="_blank" ng-click="disableIt || tellAboutIt()">
ngClick disableable link</a>
完整代码:
HTML (我已删除'禁用'属性,因为它们无法使用,因为它们不适用于锚标记):
<div ng-app="app" ng-controller="appCtrl">
<a class="disableable" target="_blank" ng-click="disableIt || tellAboutIt()">
ngClick disableable link</a>
<br/><br/>
<a class="disableable" target="_blank" href="http://google.com">
href disableable link</a>
<br/><br/>
<input type="checkbox" ng-model="disableIt" /> Disable links
</div>
Angular (我让你的指令更加紧凑):
app.directive('disableable', function($parse){
return {
restrict: 'C',
link: function (scope, elem, attrs) {
scope.$watch('disableIt', function (val) {
if (val) {
elem.addClass('disabled');
elem.css('cursor', 'default');
elem.bind('click', function(e) {
e.preventDefault();
});
}
else {
elem.removeClass('disabled');
elem.css('cursor', 'pointer');
if (typeof elem.attr('ng-click') === 'undefined')
elem.unbind('click');
}
});
}
};
});
JSFiddle:http://jsfiddle.net/KQQD2/4/
或者,您可以在$scope.disableIt
内运行代码之前检查tellAboutIt()
是否为false。 e.g:
$scope.tellAboutIt = function(){
if ($scope.disableIt === false) {
$window.alert('ngClick fired. This alert should not show when disabled.');
}
};
答案 2 :(得分:0)
我可能会采取略微不同的方式。而不是试图使用另一个指令将自己撬入ng-click。我只是编写自己的ng-click版本并使用它,然后可以使用单独的属性打开/关闭它。如果你这样做,那么你上面写的代码就不需要做太多改变就可以做到这一点,你可以用这个指令代替ng-click。
app.directive('enabled-click', function() {
return {
scope: {
enabledClick: '&',
enabled: '='
},
restrict: 'A',
link: function( scope, element, attributes ) {
element.bind('click', function(event) {
if( scope.enabled ) {
if( element.target ) {
return true; // external link
} else {
scope.enabledClick();
return false;
}
} else {
event.preventDefault();
return false;
}
} );
scope.$watch( 'enabled', function(val) {
if( val ) {
element.removeClass('disabled');
} else {
element.addClass('disabled');
}
});
}
};
});
然后使用它:
<a href="#something" enabled-click="doSomething()" enabled="!disable">Blah</a>