AngularJs Passing complex data to directive

Solution 1:

Read on Angularjs official site explanation :

@ or @attr - bind a local scope property to the value of DOM attribute. The result is always a string since DOM attributes are strings. If no attr name is specified then the attribute name is assumed to be the same as the local name. Given and widget definition of scope: { localName:'@myAttr' }, then widget scope property localName will reflect the interpolated value of hello {{name}}. As the name attribute changes so will the localName property on the widget scope. The name is read from the parent scope (not component scope).

So you can send only a string, to pass an object, you need to set-up a bi-directionnal binding using =.

   scope: {
        details: '=',
    },

And your HTML will looks like

<div teamspeak details="data.details"></div>

Solution 2:

Someone asked about how to do it without isolating scope, here is a solution:

<div teamspeak details="{{data.details}}"></div>

App.directive('teamspeak', function () {
    return {
        restrict: 'A',
        template: "<a href='ts3server://{{details.serverName.value}}:{{details.port.value}}'>Teamspeak Server</a>",
        link: function (scope, element, attrs) {
            if(attrs.details){
                scope.details = scope.$eval(attrs.details);
            }
        }
    };
});

We can even use $interpolate if any values in attrs.details should be dynamically set with angular {{...}} expressions...

scope.details = scope.$eval($interpolate(attrs.details)(scope));

(don't forget to inject $interpolate service into your directive)

Important Note: I have not tested this method with angular 2.