通过指令的 link 函数添加时,ng-click 和控制器访问会发生什么
What happens to ng-click and controller access when added by a directive's link function
<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()');
}
};
}]);
由于指令定义对象上 scope
的默认值是 false
我希望父级的范围可用,因此 attrs.$set('ng-click', 'mainCtrl.swap()');
可以工作,但确实如此单击 div
时不触发。为什么?
(N.B。我尝试按照 ppa's answer to 'AngularJS - ng-click in directive's link function' 添加 $compile
,但没有效果。)
在元素上设置属性不会处理任何指令。您必须使用 $compile
服务用当前 scope
编译新模板,并用编译后的元素替换当前元素。
.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);
}
};
在问题中我提到尝试 $compile
但我认为我在尝试时搞砸了注射。 show's how I should have done it. Here's a version of 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).
<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()');
}
};
}]);
由于指令定义对象上 scope
的默认值是 false
我希望父级的范围可用,因此 attrs.$set('ng-click', 'mainCtrl.swap()');
可以工作,但确实如此单击 div
时不触发。为什么?
(N.B。我尝试按照 ppa's answer to 'AngularJS - ng-click in directive's link function' 添加 $compile
,但没有效果。)
在元素上设置属性不会处理任何指令。您必须使用 $compile
服务用当前 scope
编译新模板,并用编译后的元素替换当前元素。
.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);
}
};
在问题中我提到尝试 $compile
但我认为我在尝试时搞砸了注射。
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).