Директива Access изолирует область действия внутри содержимого
Я не уверен, действительно ли это возможно, но я по сути нуждаюсь в обратном "&". изолировать область действия в AngularJS. Ниже представлен Plunkr.
В принципе, у меня есть настраиваемая директива, которая предоставляет некоторый HTML-код многократного использования. Он использует ng-transclude
, чтобы разрешить отображение некоторого внешнего содержимого внутри него. Тем не менее, я нашел ситуацию, когда мне хотелось бы получить доступ к функции, которая была настроена в области выделения для директивы, изнутри выделенной секции кода.
Итак, у меня есть что-то похожее:
<div ng-controller="MainController">
<!-- The directive -->
<div some-custom-directive>
<!-- Button 1 that invokes a method within the controller scope -->
<button id="button1" ng-click="invoke1()">Invoke from Controller</button>
<!-- Button 2 that invokes a method on the isolate scope for the custom directive -->
<button id="button2" ng-click="invoke2()">Invoke from Isolate Scope</button>
</div>
</div>
Кто-нибудь знает, действительно ли это возможно?
Обновление
В соответствии с ответом @Mark Rajcok, $$prevSibling
, найденный на $scope
, может использоваться для доступа к области выделения из директивы из внутриконтинентального содержимого. Тем не менее, я обновил вышеуказанный Plunkr, чтобы попытаться сделать это из директивы ng-repeat
, которая не работает. Я предполагаю, что элементы внутри этого повтора не наследуют область действия.
Ответы
Ответ 1
Хотя возможно, решение, которое я представляю, является взломом, поскольку оно использует внутреннюю переменную области видимости, $$prevSibling
.
Внутри вашего транскодированного контента вы находитесь за пределами выделенной области. Директива изолирует и трансформирует области действия - братья и сестры. Чтобы перейти из области transcluded в область выделения, вы можете использовать $$prevSibling
. (Чтобы перейти от области выделения к транслируемой области, вы можете использовать $$nextSibling
.)
Итак, этот хак будет работать:
<a href="" ng-click="$$prevSibling.action()">Invoke the Directive Action</a>
Чтобы вызвать метод в области контроллера, вам нужно указать, что с помощью &
как уже было показано @ganaraj:
<content-presenter controller-action="action()">
Затем в вашей директиве:
scope: { controllerAction: '&' },
template: ... +
'<button ng-click="controllerAction()">Trigger Ctrl action()</button>' ...
Plunker
С ng-repeat (см. комментарий Samuel) каждый элемент создает дочернюю область области, исключенной из трансляции. На рисунке ниже я показываю только один item
, чтобы уменьшить изображение. Переверните коричневую стрелку $$ nextSibling для $$ prevSibling.
![enter image description here]()
Таким образом, взломать метод action()
, определенный в области выделения из дочерней области ng-repeat,
<div ng-repeat="item in items" ng-click="$parent.$$prevSibling.action()">
Обновление для Angular v1.3 +:
Так как Angular v1.3, transcluded scope теперь является дочерним элементом области выделения атрибута – они больше не являются братьями и сестрами. Поэтому, чтобы перейти из области transcluded в область выделения, используйте $parent
.
С помощью ng-repeat каждый элемент по-прежнему создает дочернюю область области transcluded:
![enter image description here]()
Но чтобы перейти к методу action()
, определенному в области выделения из дочерней области ng-repeat, теперь мы используем
<div ng-repeat="item in items" ng-click="$parent.$parent.action()">
Ответ 2
Вот плунж, который решает вашу текущую проблему. Я не уверен, что вы пытаетесь сделать. Но, насколько я знаю, нет способа вызвать что-то в области изоляции из внешнего объема. Конечно, вы можете настроить переменную с двумя границами между областью выделения и внешней областью, изменить переменную во внешней области и $watch для нее в области выделения (это будет работать как механизм событий)... Это один способ делать то, что вы пытаетесь сделать.. если вы настаиваете на этом.
В качестве альтернативы существует механизм вызова функции во внешней области видимости из области выделения. Его вроде как обратный вызов.
Смотрите http://plnkr.co/edit/5MT4vo9qXtV6nQikfEiH?p=preview
Ответ 3
Я понимаю, что добавление ng-repeat
к элементу создает новую область видимости для правильной привязки повторяющегося содержимого. Вам может понадобиться дополнительная $parent
в этой цепочке, например $parent.$$nextSibling
, чтобы перейти на уровень, смежный с областью выделения директивы.