当由指令的链接功能添加时,ng-click和控制器访问会发生什么

时间:2015-02-20 10:43:05

标签: angularjs angularjs-directive

我有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()');
        }
    };
}]);

由于指令定义对象上scope的默认值为false,我希望父级的范围可用,因此attrs.$set('ng-click', 'mainCtrl.swap()');工作,但点击div时不会触发。为什么呢?

(N.B。我尝试按照ppa's answer to 'AngularJS - ng-click in directive's link function'添加$compile,但这没有效果。)

2 个答案:

答案 0 :(得分:1)

在元素上设置属性不会处理任何指令。您必须使用$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);
        }
    };

JSFiddle

答案 1 :(得分:1)

在问题中我提到尝试$compile,但我认为当我尝试时,我搞砸了注射。 c.P.u.1's answer显示我应该如何做到这一点。这是c.P.u.1's answer的一个版本,它不会替换当前元素,但会在添加其他属性后对其进行编译。请注意,我需要删除原始指令属性,避免无限编译循环(请参阅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)。