问题
I have a simple JSFiddle:
<div ng-controller="MainCtrl as mainCtrl">
<div ng-show="mainCtrl.visible" ng-click="mainCtrl.swap()">Can you see me?</div>
<div see-me></div>
</div>
angular.module('AngularTestApp', [])
.controller('MainCtrl', [function () {
var self = this;
self.visible = true;
self.swap = function() {
self.visible = ! self.visible;
};
}])
.directive('seeMe', [function () {
return {
template: 'or me?',
link: function (scope, element, attrs) {
attrs.$set('ng-show', 'mainCtrl.visible');
attrs.$set('ng-click', 'mainCtrl.swap()');
}
};
}]);
Since the default value for a scope
on a directive's definition object is false
I would expect the parent's scope to be available and thus for attrs.$set('ng-click', 'mainCtrl.swap()');
to work, but it does not fire when I click the div
. Why?
(N.B. I tried adding $compile
as per ppa's answer to 'AngularJS - ng-click in directive's link function' but that had no effect.)
回答1:
Setting attributes on an element doesn't process any directives. You'll have to use the $compile
service to compile the new template with the current scope
and replace the current element with the compiled element.
.directive('seeMe', ['$compile', function ($compile) {
return {
template: 'or me?',
link: function (scope, element, attrs) {
var newElement = $compile('<div ng-show="mainCtrl.visible" ng-click="mainCtrl.swap()">or me?</div>')(scope);
element.replaceWith(newElement);
}
};
JSFiddle
回答2:
In the question I mention trying $compile
but I think I messed up injection when I tried that. c.P.u.1's answer show's how I should have done it. Here's a version of c.P.u.1's answer which does not replace the current element but compiles it after the additional attributes are added. Note that I need to remove the original directive attribute avoid infinite compile loop (see Ilan Frumer's answer to 'Angular directive how to add an attribute to the element?').
HTML
<div ng-controller="MainCtrl as mainCtrl">
<div ng-show="mainCtrl.visible" ng-click="mainCtrl.swap()">Can you see me?</div>
<div see-me></div>
</div>
JavaScript
angular.module('AngularTestApp', [])
.controller('MainCtrl', [function () {
var self = this;
self.visible = true;
self.swap = function() {
self.visible = ! self.visible;
};
}])
.directive('seeMe', ['$compile', function ($compile) {
return {
template: 'or me?',
link: function (scope, element, attrs) {
element.removeAttr('see-me');
attrs.$set('ng-show', "mainCtrl.visible");
attrs.$set('ng-click', "mainCtrl.swap()");
$compile(element)(scope);
}
};
}]);
(JSFiddle here).
来源:https://stackoverflow.com/questions/28627026/what-happens-to-ng-click-and-controller-access-when-added-by-a-directives-link