What happens to ng-click and controller access when added by a directive's link function

試著忘記壹切 提交于 2019-12-25 07:58:43

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!