Peter Wone
Peter Wone

Reputation: 18805

How to set scope for AngularJS component

Suppose I build an AngularJS component

function FooController($scope, $element, $attrs, $http) {
  var ctrl = this;
  ctrl.bar = "WIBBLE";
}

angular.module("app").component("foo", {
    templateUrl: "/app/components/foo.html",
    controller: FooController,
    transclude: true
}

with a template like this that contains a transclusion tag with fallback content

[<ng-transclude>{{$ctrl.bar}}</ng-transclude>]

and I use it in a page like this

<foo></foo>

then the fallback content executes in the control scope and I get this

[WIBBLE]

But if I provide the same stuff via transclusion

<foo>{{$ctrl.bar}}</foo> 

then the transcluded content has a new isolate scope and $ctrl.bar doesn't resolve so I get

[]

How do I set the appropriate scope?

For a directive I would define the link function and use the transclude function to set the scope but component doesn't support the link function so I can't do that.

Why do Angular (1.5) components always have an isolated scope? suggests that it's flat out impossible and the answer is to use a directive instead. If that's so I'm not sure what the point of components is.

Upvotes: 0

Views: 607

Answers (1)

Peter Wone
Peter Wone

Reputation: 18805

You just plain cannot do this for a component. Refactor it as a directive and provide a link function that supplies the directive scope to the transclude function.

        transclude: true, // support <ng-transclude> in the template
        link: function (scope, element, attrs, controller, transclude) {
            var transclusionElement = element.find("ng-transclude");
            transclude(scope, function (clone, scope) {
                // link element parameter is a jQuery element
                transclusionElement.html(""); // wipe the slate
                transclusionElement.append(clone); // write the content
                // DO NOT TRY TO BE CLEVER LIKE THIS
                // transclusionElement.html(clone.html());
            });
        },

Upvotes: 0

Related Questions