在带有模板的 AngularJS 指令中使用在父作用域中创建的函数以及局部作用域变量

Using a function created in parent scope and also local scope varibles in an AngularJS directive with a template

所以我正在尝试创建一个指令,它将用 HTML 替换一个元素,其中包括一个调用在 $scope 中创建的函数的 ng-click。

可以在 http://jsfiddle.net/adinas/wbfu9ox3/5/ 找到我制作的示例 我的 HTML 是

<div ng-app="myapp" ng-controller="mycontroller">
{{greeting}}

<!--This works-->
<div xyz></div>

<!--This works-->
<div ng-click="dosomething('Click me 2')">Click me 2</div>

<!--The click added in the directive here does NOT work-->
<div abc mytext="Click me 3"></div>  

我的 JS 是

var myapp = angular.module('myapp',[]);
myapp.controller('mycontroller', ['$scope', function($scope) {
$scope.greeting = 'Hola!';

$scope.dosomething = function (what) {
    alert(what);
};
}]);
//Works
myapp.directive('xyz', function () {
    return {
        template: '<div ng-click="dosomething(\'Click me 1\')">Click me 1</div>'
    };
});
//Does not work
myapp.directive('abc', function () {
    return {
        template: '<div ng-click="dosomething(\''+attr.mytext+'\')">Click me 3</div>'
    };
});

我制作了 3 个元素。前两个显示 A. 没有指令点击工作。 B. 不使用 'dosomething' 函数的指令也有效。

尝试将参数传递给 'abc' 指令并调用函数的第三个元素失败。

如何既传递参数又使用函数?谢谢

这样的指令应该有独立的范围,这样它就可以在任何地方使用。 这是引入两个参数的简单指令:func 和 param。

app.directive('pit', function () {
    return {
        scope : {
          func: '=',
          param: '='
        },
        template: '<button ng-click="func(param)">Click me 3</button>'
    };
});

这就是你在 html 中使用它的方式:

<div pit func="test1" param="test2"></div>

我的笨蛋: http://plnkr.co/edit/YiEWchRPwX6W7bohV3Zo?p=preview

好吧,如果您查看控制台,您会看到一个错误,说明为什么这不起作用:

Error: attr is not defined

您正在尝试访问一个 attr 不存在的变量。

在指令模板中包含属性值的方法是将它们包含在指令的范围内:

scope: {
    mytext: '@'
}

这意味着指令范围内现在将有一个 mytext 变量。

然而,这会产生一个问题,因为使用 scope: {} 选项会为指令创建一个隔离范围,这意味着封闭控制器的范围不是指令范围的一部分。

如果可行,这里干净的方法是也将 dosomething 函数作为指令的参数传入:

<div abc mytext="Click me 3" action='dosomething'></div>  

return {
    template: '<div ng-click="action(mytext)">Click me 3</div>',
    scope: {
        mytext: '@',
        action: '='
    }
};

http://jsfiddle.net/jx1hgjnr/1/

但是如果这不是你想要做的并且你真的想从父范围访问 dosomething,你可以做的一件事是使用 $parent.dosomething:

return {
    template: '<div ng-click="$parent.dosomething(mytext)">Click me 3</div>',
    scope: {
        mytext: '@'
    }
};

http://jsfiddle.net/c815sqpn/1/