在属性中指定的angularjs指令调用函数并将parameter passing给它

我想创build一个链接到一个属性的指令。 该属性指定应在作用域上调用的函数。 但是我也想把一个parameter passing给链接函数里面的函数。

<div my-method='theMethodToBeCalled'></div> 

在链接函数中我绑定到一个jQuery事件,它传递一个参数,我需要传递给函数:

 app.directive("myMethod",function($parse) { restrict:'A', link:function(scope,element,attrs) { var expressionHandler = $parse(attrs.myMethod); $(element).on('theEvent',function( e, rowid ) { id = // some function called to determine id based on rowid scope.$apply(function() {expressionHandler(id);}); } } } app.controller("myController",function($scope) { $scope.theMethodToBeCalled = function(id) { alert(id); }; } 

没有通过ID我可以得到它的工作,但只要我尝试传递一个参数,函数不会被调用了

马可的解决scheme运作良好 。

与build议的Angular方式(如treeface的plunkr所示)相比,使用的是不需要定义expressionHandler的callbackexpression式。 在马可罗的例子中,

在模板中

 <div my-method="theMethodToBeCalled(myParam)"></div> 

在指令链接function

 $(element).click(function( e, rowid ) { scope.method({myParam: id}); }); 

这与marko的解决scheme相比有一个缺点 – 在第一次加载时,方法ToBeCalled函数将被myParam === undefined调用。

在@treeface Plunker上可以find工作实例

只是为其他答案添加一些信息 – 使用&是一个好方法,如果你需要一个孤立的范围。

marko的解决scheme的主要缺点是它迫使你在一个元素上创build一个独立的范围,但是你只能在元素上有一个这样的元素(否则你会遇到一个angular度错误: Multiple directives [directive1,directive2]为隔离范围

这意味着你:

  • 不能在元素帽子上使用它自己有一个孤立的范围
  • 不能在同一个元素上使用这个解决scheme的两个指令

由于原始问题使用restrict:'A'指令restrict:'A'这两种情况在较大的应用程序中可能经常出现,而在这里使用隔离范围并不是一个好的做法,也是不必要的。 实际上rekna在这种情况下有一个很好的直觉,而且几乎已经工作了,他唯一做错了的是调用$ parsed函数错误(请看这里返回的是什么: https : //docs.angularjs.org/api/ ng / service / $ parse )。

TL; DR; 修复了问题代码

 <div my-method='theMethodToBeCalled(id)'></div> 

和代码

 app.directive("myMethod",function($parse) { restrict:'A', link:function(scope,element,attrs) { // here you can parse any attribute (so this could as well be, // myDirectiveCallback or multiple ones if you need them ) var expressionHandler = $parse(attrs.myMethod); $(element).on('theEvent',function( e, rowid ) { calculatedId = // some function called to determine id based on rowid // HERE: call the parsed function correctly (with scope AND params object) expressionHandler(scope, {id:calculatedId}); } } } app.controller("myController",function($scope) { $scope.theMethodToBeCalled = function(id) { alert(id); }; } 

不知道你想要做什么,但仍然是一个可能的解决scheme。

在本地范围内使用“&” – 属性创build范围。 它“提供了一种在父范围的上下文中执行expression式的方法”(有关详细信息,请参阅指令文档 )。

我也注意到,你使用了一个简写连接函数,并在那里的对象属性中推进。 你不能这样做。 只是返回指令定义对象更加清楚(imho)。 看到我的代码如下。

这是一个代码示例和小提琴 。

 <div ng-app="myApp"> <div ng-controller="myController"> <div my-method='theMethodToBeCalled'>Click me</div> </div> </div> <script> var app = angular.module('myApp',[]); app.directive("myMethod",function($parse) { var directiveDefinitionObject = { restrict: 'A', scope: { method:'&myMethod' }, link: function(scope,element,attrs) { var expressionHandler = scope.method(); var id = "123"; $(element).click(function( e, rowid ) { expressionHandler(id); }); } }; return directiveDefinitionObject; }); app.controller("myController",function($scope) { $scope.theMethodToBeCalled = function(id) { alert(id); }; }); </script> 

您可以创build一个指令,通过使用attrName: "&"引用外部expression式中的expression式来执行带有参数的函数调用。

我们要用ng-click-xreplaceng-click指令:

 <button ng-click-x="add(a,b)">Add</button> 

如果我们有这个范围:

 $scope.a = 2; $scope.b = 2; $scope.add = function (a, b) { $scope.result = parseFloat(a) + parseFloat(b); } 

我们可以这样编写我们的指令:

 angular.module("ng-click-x", []) .directive('ngClickX', [function () { return { scope: { // Reference the outer scope fn: "&ngClickX", }, restrict: "A", link: function(scope, elem) { function callFn () { scope.$apply(scope.fn()); } elem[0].addEventListener('click', callFn); } }; }]); 

这是一个现场演示: http : //plnkr.co/edit/4QOGLD?p=info

这是为我工作的。

Html使用指令

  <tr orderitemdirective remove="vm.removeOrderItem(orderItem)" order-item="orderitem"></tr> 

Html的指令:orderitem.directive.html

 <md-button type="submit" ng-click="remove({orderItem:orderItem})"> (...) </md-button> 

指令的范围:

 scope: { orderItem: '=', remove: "&", 

我的解决scheme

  1. 聚合物引发事件(例如complete
  2. 定义一个把事件和控制function联系起来的指令

指示

 /*global define */ define(['angular', './my-module'], function(angular, directives) { 'use strict'; directives.directive('polimerBinding', ['$compile', function($compile) { return { restrict: 'A', scope: { method:'&polimerBinding' }, link : function(scope, element, attrs) { var el = element[0]; var expressionHandler = scope.method(); var siemEvent = attrs['polimerEvent']; if (!siemEvent) { siemEvent = 'complete'; } el.addEventListener(siemEvent, function (e, options) { expressionHandler(e.detail); }) } }; }]); }); 

聚合物组分

 <dom-module id="search"> <template> <h3>Search</h3> <div class="input-group"> <textarea placeholder="search by expression (eg. temperature>100)" rows="10" cols="100" value="{{text::input}}"></textarea> <p> <button id="button" class="btn input-group__addon">Search</button> </p> </div> </template> <script> Polymer({ is: 'search', properties: { text: { type: String, notify: true }, }, regularSearch: function(e) { console.log(this.range); this.fire('complete', {'text': this.text}); }, listeners: { 'button.click': 'regularSearch', } }); </script> </dom-module> 

  <search id="search" polimer-binding="searchData" siem-event="complete" range="{{range}}"></siem-search> 

searchData是控制function

 $scope.searchData = function(searchObject) { alert('searchData '+ searchObject.text + ' ' + searchObject.range); } 

这应该工作。

 <div my-method='theMethodToBeCalled'></div> app.directive("myMethod",function($parse) { restrict:'A', scope: {theMethodToBeCalled: "="} link:function(scope,element,attrs) { $(element).on('theEvent',function( e, rowid ) { id = // some function called to determine id based on rowid scope.theMethodToBeCalled(id); } } } app.controller("myController",function($scope) { $scope.theMethodToBeCalled = function(id) { alert(id); }; }