angular度指令是否可以将指令的parameter passing给指令的属性中指定的expression式?
我有一个表单指令,使用隔离范围指定的callback
属性:
scope: { callback: '&' }
它位于ng-repeat
内部,所以我传递的expression式包含作为callback函数参数的对象的id
:
<directive ng-repeat = "item in stuff" callback = "callback(item.id)"/>
当我完成了指令,它从它的控制器函数中调用$scope.callback()
。 对于大多数情况下,这是好的,这是我想要做的,但有时我想从directive
本身添加另一个参数。
是否有一个angular度expression式可以允许: $scope.callback(arg2)
,导致callback
被调用arguments = [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]) );
但我不认为它特别整齐,而且涉及到在隔离范围内增加额外的东西。
有没有更好的办法?
这里的游戏机操场 (打开游戏机)。
如果你像@ lex82所说的那样声明你的callback
callback = "callback(item.id, arg2)"
您可以使用对象映射调用指令范围中的callback方法,并正确执行绑定。 喜欢
scope.callback({arg2:"some value"});
而不需要$parsing。 看我的小提琴(控制台日志) http://jsfiddle.net/k7czc/2/
更新 :在文档中有一个这样的例子:
&或&attr – 提供一种在父范围的上下文中执行expression式的方法。 如果没有指定attr名称,则假定属性名称与本地名称相同。 给定范围的小部件定义:{localFn:'&myAttr'},然后隔离范围属性localFn将指向count = count + valueexpression式的函数包装。 通常希望通过expression式向父范围传递来自独立范围的数据,这可以通过将局部variables名称和值的映射传递到expression式包装函数fn来完成。 例如,如果expression式是增量(金额),那么我们可以通过调用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);
在其他嵌套场景中哪个会失败。
我从Dan Wahlin的一篇优秀文章中调整了这一技术, url是http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-3-isolate-scope-and-function-parameters
我添加了解包步骤来调用函数更自然,并解决了我在项目中遇到的嵌套问题。
在指令( 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
,并设置为item
。
要从指令的link
属性(“内部”)中调用,使用非常类似的方法:
... directive.link = function(isolatedScope) { isolatedScope.boundFunction({param: "foo"}); }; ... return directive;
是的,还有一个更好的方法:可以在指令中使用$ parse服务来在父范围的上下文中计算expression式,同时将expression式中的某些标识符绑定到仅在指令中可见的值:
$parse(attributes.callback)(scope.$parent, { arg2: yourSecondArgument });
将此行添加到指令的链接函数中,您可以在其中访问指令的属性。
您的callback属性可能会被设置为callback = "callback(item.id, arg2)"
因为arg2通过指令中的$ parse服务绑定到yourSecondArgument。 象ng-click
这样的指令可以让你通过使用这个机制传递给指令的expression式中的$event
标识符来访问click事件。
请注意,您不必使用此解决scheme将callback
作为隔离范围的成员。