Угловая директива с использованием изолированных областей

Я пытаюсь создать директиву Angular, которая берет некоторые данные и изменяет переменную области видимости на основе ввода, но я не могу заставить ее работать.

Вот упрощенная версия моего JS:

var module = angular.module('myapp', []);

module.directive('checkDirective', function() {
  return {
    restrict: 'E',
    scope: { line: '@' },
    transclude: true,
    controller: function($scope) {
        $scope.newLine = $scope.line;
    },
    template: '<div ng-transclude></div>'
  };
});

И вот мой HTML:

<div ng-app="myapp">                           
    0
    <check-directive line="...">
        a{{line}}b{{newLine}}c
    </check-directive>
    1
</div>

Скрипка для этого находится здесь: http://jsfiddle.net/k66Za/60/

Любая помощь будет оценена по достоинству!


person FrankS    schedule 17.02.2015    source источник
comment
Я думаю, что ваша изолированная область в вашей директиве недоступна для контроллера. Посмотрите на этот ответ: stackoverflow.com/a/16735433/1454888. Надеюсь, поможет   -  person Augusto Barreto    schedule 18.02.2015


Ответы (2)


Включенная область HTML является дочерней областью родителя, а не областью действия директивы. Вы можете использовать функцию transclude, которая передается функции связывания директивы, чтобы изменить область действия.

link: function (scope, elem, attrs, ctrl, transcludeFn) {
  transcludeFn(scope, function (clone, scope) {
    elem.append(clone);
  });
}

http://jsfiddle.net/k66Za/64/

Однако я бы не рекомендовал этого делать. Вместо этого для меня имеет смысл предположить, что включенный контент будет использовать отдельную область действия и работать с ней. Вы также можете создать отдельную директиву, если это необходимо.

person Explosion Pills    schedule 17.02.2015
comment
Не технически правильно. Включение по умолчанию создает новую область, которая является дочерней по отношению к родительской области (которая прототипически наследуется от родителя). Эта область является родственной директивной области. Это незначительная деталь, но она может иметь интересные и нежелательные побочные эффекты, если вы считаете иначе. - person Joe Enzminger; 18.02.2015

Это связано с тем, что включенный HTML использует не изолированную область действия директивы, а ее родителя. Чтобы использовать правильную область видимости, используйте специальный параметр transclude функции ссылки.

Кроме того, @ означает, что angular ожидает выражение между фигурными скобками, например {{someVariable}} или {{ 'someString' }}.

http://jsfiddle.net/floribon/r611o3sa/

module.directive('checkDirective', function() {
  return {
    restrict: 'E',
    scope: { line: '@' },
    transclude: true,
    link: function(scope, element, attrs, ctrl, transclude) {   
      var isolatedScope = scope;

      transclude(scope.$parent, function(clone, scope) {
        scope.line = isolatedScope.line;
        scope.newLine = scope.line;
      });
    },
    template: '<div ng-transclude></div>'
  };
});

Вы можете узнать больше о включении здесь: http://angular-tips.com/blog/2014/03/transclusion-and-scopes/

person floribon    schedule 17.02.2015