директива angularjs вызывает функцию, указанную в атрибуте, и передает ей аргумент
Я хочу создать директиву, которая ссылается на атрибут. Атрибут определяет функцию, которая должна быть вызвана в области видимости. Но я также хочу передать аргумент функции, которая определена внутри функции link.
<div my-method='theMethodToBeCalled'></div>
в функции link я привязываюсь к событию 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); };
}
без прохождения ИД я могу заставить его работать, но как только я пытаюсь передать аргумент, функция больше не называется
7 ответов:
Марко решения.
для контраста с рекомендуемым угловым способом (как показано в plunkr treeface) следует использовать выражение обратного вызова, которое не требует определения expressionHandler. В Примере Марко изменить:
в шаблоне
<div my-method="theMethodToBeCalled(myParam)"></div>в директиве link функции
$(element).click(function( e, rowid ) { scope.method({myParam: id}); });это имеет один недостаток по сравнению с решением Марко - при первой загрузке theMethodToBeCalled функция будет вызвана с помощью myParam === неопределено.
рабочий пример можно найти в @treeface Plunker
просто чтобы добавить некоторую информацию к другим ответам-используя
&это хороший способ, если вам нужна изолированная область.основной недостаток решения Марко заключается в том, что он заставляет вас создавать изолированную область видимости на элементе, но вы можете иметь только один из них на элементе (в противном случае вы столкнетесь с угловой ошибкой: несколько директив [directive1, directive2] запрашивают изолированную область)
Это означает, что вы :
- не могу использовать его на элемент hat имеет изолированную область сам
- не может использовать две директивы с этим решением на одном элементе
так как исходный вопрос использует директиву с
restrict:'A'обе ситуации могут возникать довольно часто в больших приложениях, и использование изолированной области здесь не является хорошей практикой, а также ненужным. На самом деле у рекны была хорошая интуиция в этом случае, и почти она работала, единственное, что он делал неправильно, это называл $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); }; }
Не зная точно, что вы хотите сделать... но все же вот возможное решение.
создайте область с '& ' - свойством в локальной области. Он "предоставляет способ выполнения выражения в контексте родительской области" (см. директива документации для деталей).
Я также заметил, что вы использовали функцию сокращенного связывания и вставляли туда атрибуты объекта. Ты не можешь этого сделать. Это более ясно (имхо), чтобы просто вернуть директива-объект определения. Смотрите мой код ниже.
вот пример кода скрипка.
<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>
вы можете создать директиву, которая выполняет вызов функции с параметрами с помощью
attrName: "&"для ссылки на выражение во внешней области.мы хотим заменить
вот что сработало для меня.
Html с помощью директивы
<tr orderitemdirective remove="vm.removeOrderItem(orderItem)" order-item="orderitem"></tr>Html директивы: orderitem.директива.HTML-код
<md-button type="submit" ng-click="remove({orderItem:orderItem})"> (...) </md-button>область действия директивы:
scope: { orderItem: '=', remove: "&",
мое решение:
- на полимер поднять событие (например.
complete)- определите директиву, связывающую событие с функцией управления
директива
/*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функция контроля$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); }; }
Comments