我有ng-click="foo()"
警告“foo”
在我自己的指令中,如果找到ng-click,我想添加另一个函数来提醒“bar”
我试过这个 演示:http://plnkr.co/edit/1zYl0mSxeLoMU3yjoGBV?p=preview
它不起作用
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="http://code.angularjs.org/1.2.7/angular.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('MyCtrl', function($scope) {
$scope.foo = function() { alert('foo'); }
$scope.bar = function() { alert('bar'); }
});
app.directive("myAttr", function() {
return {
link: function(scope, el, attrs) {
el.attr('ng-click', attrs.ngClick+';bar()');
}
}
})
</script>
</head>
<body ng-controller="MyCtrl">
<a my-attr ng-click="foo()" href="">click here!</a>
</body>
</html>
我也无法使用另一个ng- *指令来使其工作,即el.attr('ng-focus', 'bar()');
。似乎在渲染后我无法更改或添加ng- *指令。
我怎样才能做到这一点,我做错了什么?
答案 0 :(得分:4)
app.directive("myAttr", function() {
return {
priority: 1,
compile: function(el, attrs) {
attrs.ngClick += ';bar()';
}
}
})
首先,您需要compile
函数,因为在调用link
时,ng-click
指令已经设置。
第二个重要的是改变优先级。您希望确保在ng-click
之前调用您的指令。 ng-click
的默认优先级为0,因此1就足够了。
最后也是最重要的一点是,你不想改变元素,而是attrs
本身。每个元素只创建一次。因此,当ng-click
访问它时,如果您直接更改了元素的属性,它仍将包含相同的值。
答案 1 :(得分:2)
我认为你可以用ngTransclude
做你想做的事。
app.directive("myAttr", function() {
return {
transclude:true,
template: '<span ng-click="bar()" ng-transclude></span>',
link: function(scope, el, attrs) {
}
}
});
这有用吗?
修改强>
好的,这个呢?
app.directive("myAttr", function($compile) {
return {
link: function(scope, el, attrs) {
el.attr('ng-click', 'bar()');
el.removeAttr('my-attr');
$compile(el)(scope);
}
}
});
答案 2 :(得分:2)
虽然这可以通过上面概述的编译来完成,但是这种方法并不能保证ng-click项目被添加到DOM节点的顺序(正如您已经发现的那样),并且本质上很慢(如已经被像贾里德这样的词语指出了。
就个人而言,我会做这样的事情:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<link rel="stylesheet" href="style.css">
<script src="http://code.angularjs.org/1.2.7/angular.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('MyCtrl', function($scope) {
$scope.foo = function() { alert('foo'); }
$scope.bar = function() { alert('bar'); }
});
app.directive('myAttr', function() {
return {
scope: true,
link: function(scope, el, attrs) {
if(attrs.hasOwnProperty('ngClick')){
scope.foo = function(){
scope.$parent.foo();
scope.$parent.bar();
}
}
}
};
});
</script>
</head>
<body ng-controller="MyCtrl">
<a my-attr ng-click="foo()" href="">click here!</a>
</body>
</html>
发生了什么事:
scope: true
:默认情况下,指令不会创建新范围,只是共享其父范围。通过设置scope: true
,该指令的每个实例都将创建一个子范围,它将原型继承父范围。
然后你可以简单地覆盖所需的方法(foo()
)和瞧
现场演示:
答案 3 :(得分:0)
我坦率地承认,我可能会完全误解你要做的事情。但是,考虑到您提供的示例,我认为通过更多地分离问题可能会更好。
从您的示例中可以看出,只要您的指令存在,您就会尝试一起触发foo
和bar
。如果foo
和bar
都是控制器的问题,那么为什么不将它们包装在另一个函数中并将该函数分配给元素的ng-click
。如果foo
是控制器的问题,但bar
是指令的关注点,为什么不直接从指令代码触发bar
功能?
如果假设“foo”和“bar”中包含的功能由控制器创建者定义...
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<link rel="stylesheet" href="style.css">
<script src="http://code.angularjs.org/1.2.7/angular.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('MyCtrl', function($scope) {
$scope.foo = function() { alert('foo'); }
$scope.bar = function() { alert('bar'); }
$scope.pak = function() {
$scope.foo();
$scope.bar();
}
});
</script>
</head>
<body ng-controller="MyCtrl">
<a ng-click="pak()" href="">click here!</a>
</body>
</html>
或者,如果“foo”中包含的功能假设由控制器创建者定义,但“bar”中包含的功能假定由指令创建者定义... 强>
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<link rel="stylesheet" href="style.css">
<script src="http://code.angularjs.org/1.2.7/angular.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('MyCtrl', function($scope) {
$scope.foo = function() { alert('foo'); }
});
app.directive('myAttr', function(){
return {
link: function(scope, element, attrs){
element.click(function(){
alert('bar');
});
}
}
});
</script>
</head>
<body ng-controller="MyCtrl">
<a ng-click="foo()" href="">click here!</a>
</body>
</html>