角度指令可以将参数传递给指令属性中指定的表达式中的函数吗?

我有一个表单指令,它使用具有隔离作用域的指定 callback属性:

scope: { callback: '&' }

它位于一个 ng-repeat中,所以我传入的表达式包括对象的 id作为回调函数的参数:

<directive ng-repeat = "item in stuff" callback = "callback(item.id)"/>

当我完成指令后,它从它的控制器函数调用 $scope.callback()。对于大多数情况,这样做是可以的,这也是我想要做的,但是有时我想从 directive本身内部添加另一个参数。

是否有一个角度表达式允许这样: $scope.callback(arg2),导致 callbackarguments = [item.id, arg2]调用?

如果没有,那么最简单的方法是什么?

我发现这个方法很有效:

<directive
ng-repeat = "item in stuff"
callback = "callback"
callback-arg="item.id"/>

scope { callback: '=', callbackArg: '=' }

和指令调用

$scope.callback.apply(null, [$scope.callbackArg].concat([arg2, arg3]) );

但我不认为这是特别整洁,它涉及到把额外的东西在隔离范围。

还有更好的办法吗?

普朗克游乐场在这里 (控制台打开)。

139402 次浏览

是的,有一个更好的方法: 您可以使用指令中的 $解析服务在父范围的上下文中计算表达式,同时将表达式中的某些标识符绑定到只能在指令中看到的值:

$parse(attributes.callback)(scope.$parent, { arg2: yourSecondArgument });

将此行添加到指令的链接函数中,您可以在该函数中访问指令的属性。

然后可以像 callback = "callback(item.id, arg2)"那样设置回调属性,因为 arg2是通过指令内部的 $parse 服务绑定到 yourSecond Argument 的。像 ng-click这样的指令允许您通过传递给指令的表达式中的 $event标识符访问 click 事件,具体方法就是使用这种机制。

注意,使用此解决方案时,不必使 callback成为独立作用域的成员。

如果像@lex82中提到的那样声明回调,则为

callback = "callback(item.id, arg2)"

您可以使用对象映射调用指令范围中的回调方法,它将正确地执行绑定。喜欢

scope.callback({arg2:"some value"});

不需要 $parse。查看我的小提琴(控制台日志) http://jsfiddle.net/k7czc/2/

更新 : 在 文件中有一个小例子:

& or & attr-提供了在 如果没有指定 attr 名称,那么属性名 假定与本地名称相同。范围的给定和小部件定义: { “ & myAttr”} ,然后隔离作用域属性 localFn 将指向 Count = count + value 表达式的函数包装器 希望通过表达式从隔离的作用域传递数据 对于父作用域,可以通过传递 local 的映射来实现 变量名和值放入表达式包装器 fn. < strong > < em > 例如, 如果表达式是增量(amount) ,那么我们可以指定金额 通过将 localFn 调用为 localFn ({ amount: 22})获取。

其他答案没有问题,但是当在指令属性中传递函数时,我使用以下技术。

当在 html 中包含指令时,去掉括号:

<my-directive callback="someFunction" />

然后“解开”指令链接或控制器中的函数。下面是一个例子:

app.directive("myDirective", function() {


return {
restrict: "E",
scope: {
callback: "&"
},
template: "<div ng-click='callback(data)'></div>", // call function this way...
link: function(scope, element, attrs) {
// unwrap the function
scope.callback = scope.callback();


scope.data = "data from somewhere";


element.bind("click",function() {
scope.$apply(function() {
callback(data);                        // ...or this way
});
});
}
}
}]);

“取消包装”步骤允许使用更自然的语法调用函数。它还确保指令正常工作,甚至当嵌套在其他指令,可以传递函数。如果你没有拆封,那么如果你有这样的情况:

<outer-directive callback="someFunction" >
<middle-directive callback="callback" >
<inner-directive callback="callback" />
</middle-directive>
</outer-directive>

然后你会在你的内在指令中得到这样的结果:

callback()()()(data);

在其他嵌套场景中会失败。

我从 http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-3-isolate-scope-and-function-parameters的 Dan Wahlin 的一篇优秀文章中改编了这种技术

我添加了展开步骤,以使调用函数更加自然,并解决了我在一个项目中遇到的嵌套问题。

指令(myDirective) :

...
directive.scope = {
boundFunction: '&',
model: '=',
};
...
return directive;

指令模板:

<div
data-ng-repeat="item in model"
data-ng-click='boundFunction({param: item})'>
\{\{item.myValue}}
</div>

来源:

<my-directive
model='myData'
bound-function='myFunction(param)'>
</my-directive>

控制器中定义了 myFunction

注意,指令模板中的 param整齐地绑定到源代码中的 param,并被设置为 item


要从指令的 link属性内部调用(“ inside”of it) ,使用非常类似的方法:

...
directive.link = function(isolatedScope) {
isolatedScope.boundFunction({param: "foo"});
};
...
return directive;

对我来说,以下方法奏效了:

在指令中声明如下:

.directive('myDirective', function() {
return {
restrict: 'E',
replace: true,
scope: {
myFunction: '=',
},
templateUrl: 'myDirective.html'
};
})

在指令模板中,它的使用方式如下:

<select ng-change="myFunction(selectedAmount)">

然后当你使用指令时,像这样传递函数:

<data-my-directive
data-my-function="setSelectedAmount">
</data-my-directive>

通过声明传递函数,然后从指令中调用函数并填充参数。