在属性中指定的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-x
replaceng-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
- 聚合物引发事件(例如
complete
) - 定义一个把事件和控制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); }; }