3

I'm trying to pass a JSON object from an Angular service to a directive. Actually I just want to $compile a directive on-the-go and pass an object to the directive.

It should look something like this:

var template = '<gmap-info-window layer="layer" marker="marker"></gmap-info-window>',
    content = $compile(template)(searchScope);

Whereas the directive looks like this:

.directive('gmapInfoWindow', [function() {
    scope: {
        marker: '=',
        layer: '='
    },
    link: function(scope, element, attrs) {
        // access objects in attrs
    }
}]);

That doesn't work. All I get in the attrs.marker and attrs.layer is plain strings.

Now what I've tried and accomlished is using the transcludeFn function of the $compile function. It works, but I don't feel it being the right way to do what I'm trying to accomplish.

 var template = '<gmap-info-window></gmap-info-window>',
     content = $compile(template)(searchScope, null, {
         parentBoundTranscludeFn: function() {
              return {
                  marker: _marker,
                  layer: _layer
              };
          }
      });

Whereas the directive looks like this:

.directive('gmapInfoWindow', [function() {
    scope: {},
    link: function(scope, element, attrs, controller, transcludeFn) {
        var objects = transcludeFn();
        // The marker and layer are in objects now!
    }
}]);

I can't imagine that there's no other way to do what I wanna do. This looks kinda dirty. Thanks for your insight!

1 Answer 1

3

All I get in the attrs.marker and attrs.layer is plain strings.

You need to understand that attribute is always a string by definition. It not possible that you have an object there. What Angular does is it evaluates values of those attributes (strings) in proper context (scope of compilation) according to scope configuration of the directive. Then the result of this evaluation is available in scope object of the link function. This is what you need to use:

link: function(scope, element, attrs) {
    console.log(scope.marker, scope.layer);
}
Sign up to request clarification or add additional context in comments.

5 Comments

Okay, but if I have multiple directives of the same type they all seem to have the same scope.
No, they all have isolated scope according to your configuration. Not sure how you are using it though. Can you reproduce your issue here?
Hey, thanks for helping out. Late reply of mine. check this plunker. Either I use the scope as commented out (which doesnt work as expected) or I set it to scope:true, which does work, but then every instance of the directive shares the same scope.
No, directives don't share the same scope, they have isolated scopes. However, both of them point to the same object in the outer scope. This pointer is set up via scope config. Remember, that object are passed by reference. In the first iteration layer is "layer" and layer: {my: 'layer'} and this object is passed into the first instance of the directive. Next iteration changes this object to layer: {my: 'other_layer'} and since the first one uses the same object you have in impression that scopes are the same. However, it's the $scope.layer object is the same.
Here is an example of passing different object into different directives: plnkr.co/edit/iIi03dvOUg8lgJe1T57x?p=info

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.