У меня есть директива формы, которая использует указанный callback
атрибут с изолированной областью:
scope: { callback: '&' }
Он находится внутри выражения ng-repeat
так, что я передаю, включает в себя id
объект в качестве аргумента функции обратного вызова:
<directive ng-repeat = "item in stuff" callback = "callback(item.id)"/>
Когда я закончил с директивой, она вызывает $scope.callback()
функцию контроллера. В большинстве случаев это нормально, и это все, что я хочу сделать, но иногда я хотел бы добавить еще один аргумент изнутри самого directive
себя.
Есть ли угловое выражение, которое позволило бы это: в $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]) );
Но я не думаю, что это особенно опрятно и включает в себя добавление дополнительных вещей в область видимости.
Есть ли способ лучше?
Здесь есть плункерная площадка (консоль открыта).
источник
ng
API, например,ng-click="someFunction()"
является выражением, которое оценивает выполнение функции.$scope.callback
устанавливаетсяcallback="someFunction"
атрибут иscope: { callback: '=' }
свойство объекта определения директивы.$scope.callback
это функция будет называться на более поздний срок. Фактическое значение атрибута, очевидно, является строкой - это всегда имеет место с HTML.Ответы:
Если вы объявите свой обратный вызов, как упомянуто @ lex82, как
Вы можете вызвать метод обратного вызова в области действия директивы с картой объекта, и он будет выполнять привязку правильно. подобно
не требуя для разбора $. Смотрите мою скрипку (журнал консоли) http://jsfiddle.net/k7czc/2/
Обновление : есть небольшой пример этого в документации :
источник
Ничего плохого в других ответах, но я использую следующую технику при передаче функций в атрибуте директивы.
Не включайте скобки при включении директивы в ваш HTML:
Затем «разверните» функцию в ссылке или контроллере вашей директивы. вот пример:
Шаг «разворачивания» позволяет вызывать функцию с использованием более естественного синтаксиса. Это также обеспечивает правильную работу директивы, даже если она вложена в другие директивы, которые могут передавать функцию. Если вы не делали развертывание, то если у вас есть такой сценарий:
Тогда вы получите что-то вроде этого в вашей внутренней директиве:
Который потерпит неудачу в других сценариях вложенности.
Я адаптировал эту технику из превосходной статьи Дэна Уолина на http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-3-isolate-scope-and-function-parameters.
Я добавил шаг развертывания, чтобы сделать вызов функции более естественным и решить проблему с вложенностью, с которой я столкнулся в проекте.
источник
this
указатель внутри метода обратного вызова, потому что он использует область действия директивы. Я использую Typescript и мой обратный вызов выглядит так:public validateFirstName(firstName: string, fieldName: string): ng.IPromise<boolean> { var deferred = this.mQService.defer<boolean>(); ... .then(() => deferred.resolve(true)) .catch((msg) => { deferred.reject(false); }); return deferred.promise; }
В директиве (
myDirective
):В директиве шаблона:
В источнике:
... где
myFunction
определяется в контроллере.Обратите внимание, что
param
в директиве шаблон аккуратно привязывается кparam
источнику и имеет значениеitem
.Для вызова изнутри
link
свойства директивы («inside») используйте очень похожий подход:источник
Да, есть лучший способ: вы можете использовать службу $ parse в вашей директиве для оценки выражения в контексте родительской области, связывая определенные идентификаторы в выражении со значениями, видимыми только внутри вашей директивы:
Добавьте эту строку в функцию ссылки директивы, где вы можете получить доступ к атрибутам директивы.
Ваш атрибут обратного вызова может затем быть установлен как,
callback = "callback(item.id, arg2)"
потому что arg2 связан с yourSecondArgument сервисом $ parse внутри директивы. Такие директивы, какng-click
позволяют вам получить доступ к событию click через$event
идентификатор внутри выражения, переданного директиве, используя именно этот механизм.Обратите внимание, что вы не должны входить в
callback
изолированную область с помощью этого решения.источник
scope.$parent
делает директиву «неплотной» - она «знает» слишком много о внешнем мире, чего не должен делать хорошо разработанный инкапсулированный компонент.У меня работает следующее:
в директиве объявить это так:
В шаблоне директивы используйте его следующим образом:
И затем, когда вы используете директиву, передайте функцию следующим образом:
Вы передаете функцию по ее объявлению, и она вызывается из директивы, а параметры заполняются.
источник