Директива Access изолирует область действия внутри содержимого - программирование
Подтвердить что ты не робот

Директива 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, которая не работает. Я предполагаю, что элементы внутри этого повтора не наследуют область действия.

4b9b3361

Ответ 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, чтобы перейти на уровень, смежный с областью выделения директивы.