Генерация области действия в шаблоне директивы не работает с включением

Как определить директиву в Angularjs, которая получает параметры и включает подэлементы с помощью ngIf или ngRepeat?

Полную демонстрацию проблемы можно найти здесь — http://jsfiddle.net/2aa47/4/. Вот HTML:

<div ng-controller='myController'>
    <my-directive condition="flag">
        Both 'flag' and 'a' are defined on controller's scope.
        Hi. {{a}} -> Nothing is shown after 'Hi'.
    </my-directive>
</div>

И сценарий. В моей реальной проблеме у меня значительно больший шаблон с ngIf посередине.

app.directive('myDirective', function () {
    return {
        restrict: 'E',
        transclude: true,
        scope: { condition: '=condition' },
        template: '<div ng-if="condition" ng-transclude></div>'
    };
});

Чтобы получить директиву параметров, необходимо создать изолированную область. И ngIf, и ngRepeat, и другие подобные директивы создадут область, которая наследуется от этой изолированной области. Затем включенные элементы получат область действия более позднего, то есть непосредственно под изолированным элементом директивы:

Controller's scope
  Directive's isolated scope
    Scope created by ngIf
    Element transcluded by directive. Should be directly under controller's scope

Теперь включенные элементы внутри директивы не могут получить доступ к области действия контроллера. Как смягчить это?

Для справки, в проекте Angular есть такая проблема — https://github.com/angular/angular.js/issues/1809.


person Ilia Barahovski    schedule 16.03.2014    source источник


Ответы (1)


Я предложил обходной путь для этого здесь.

Внедрив setTransscope в вашу директиву и вызвав ее на этапе связывания, правильная область помечается для включения. Вместо использования директивы ng-transclude в шаблоне следует использовать директиву ng-transscope, которая восстанавливает отмеченную ранее область.

Директива

myApp.directive('myDirective', function(setTransscope) {
  return {
    scope: {
      display: "="
    },
    transclude: true,   // required
    restrict: 'EA',
    templateUrl: 'my-template.html',
    link: setTransscope

    /* ... or call within your own link function:
    link: function($scope, $element) {
      setTransscope($scope, $element);

      // ...
      // Other stuff
      // ...
    } */

  };
});

Шаблон

<div ng-if="display">
  <div ng-transscope></div>
</div>
person null    schedule 16.03.2014
comment
Большое тебе спасибо. Проверено — jsfiddle.net/2aa47/10. У меня была проблема только со звонком на $element.empty();. По какой-то причине empty было подчеркнуто. Директива видимо работала и без него. И дампер области видимости кажется мощным и простым инструментом отладки. - person Ilia Barahovski; 17.03.2014