I have the following directive:
<div teamspeak details="{{data.details}}"></div>
this is the object structure:
data: { details: { serverName: { type: 'text', value: 'my server name' }, port: { type: 'number', value: 'my port' }, nickname: { type: 'text' }, password: { type: 'password' }, channel: { type: 'text' }, channelPassword: { type: 'password' }, autoBookmarkAdd: { type: 'checkbox' } } }
and I want it to generate a link based on the data inside the data.details
object. Unfortunately it doesn't work since somehow I cann't access any inner values of the details
object, but if I am passing it a simple data structure like:
<div teamspeak details="{{data.details.serverName.value}}"></div>
I can access it by using {{details}}
.
Here is my Directive Code:
App.directive('teamspeak', function () { return { restrict: 'A', template: "<a href='ts3server://{{details.serverName.value}}:{{details.port.value}}'>Teamspeak Server</a>", scope: { details: '@details', }, link: function (scope, element, attrs) { } }; });
Thanks
The best way to pass an object to an angular directive is by using the &. When you use &, angular compiles the string as an expression and sets the scope variable in your directive to a function that, when called, will evaluate the expression in the context of the directive's parent's scope.
Using attrs you are able to access the attributes defined in your html tag like <fm-rating ng-model="$parent.restaurant.price" symbol="$" readonly="true"> So in this case you will have access to the symbol and readonly attributes.
Define custom directive to handle above custom html tags. var mainApp = angular. module("mainApp", []); //Create a directive, first parameter is the html element to be attached. //We are attaching student html tag. //This directive will be activated as soon as any student element is encountered in html mainApp.
The restrict option is typically set to: 'A' - only matches attribute name. 'E' - only matches element name. 'C' - only matches class name. 'M' - only matches comment.
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>
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With