1

I'm trying to make an Angular directive which takes some data and modifies a scope variable based on the input, but I can't get it to work.

Here is a simplified version of my 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>'
  };
});

And here is my HTML:

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

A fiddle for it is here: http://jsfiddle.net/k66Za/60/

Any help would be appreciated!

yangli-io
  • 16,760
  • 8
  • 37
  • 47
FrankS
  • 11
  • 1
  • I think your isolated scope in your directive is not accessible to the controller. Look at this answer: http://stackoverflow.com/a/16735433/1454888. Hope it helps – Augusto Barreto Feb 17 '15 at 21:55

2 Answers2

1

Transcluded HTML scope is a child of the parent's scope, not the directive scope. You can use the transclude function that is passed to the directive's linking function to change the scope.

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

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

I wouldn't recommend doing this, though. Instead it makes more sense to me to assume that the transcluded content is going to be using a separate scope and work with that. You can create a separate directive too if need be.

Explosion Pills
  • 188,624
  • 52
  • 326
  • 405
  • Not technically correct. Transclusion, by default, creates a new scope that is a child of the parent scope (that prototypically inherits from the parent). This scope is a sibling of the directive scope. It is a minor detail, but can have interesting and undesirable side effects if you assume otherwise. – Joe Enzminger Feb 17 '15 at 22:07
-1

That's because the transcluded HTML doesn't use the isolated scope of the directive, but the one of its parent. The way to use the right scope is using the specific transclude parameter of the link function.

Also, @ means angular expect an expression between curly brackets, such as {{someVariable}} or {{ '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>'
  };
});

You should read more about transclusion here: http://angular-tips.com/blog/2014/03/transclusion-and-scopes/

floribon
  • 19,175
  • 5
  • 54
  • 66