Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJs Passing complex data to directive

Tags:

angularjs

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

like image 278
Aviran Cohen Avatar asked Sep 22 '13 02:09

Aviran Cohen


People also ask

How do I pass data from one directive to another directive in AngularJS?

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.

What is attrs in AngularJS?

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.

How to make custom directive in AngularJS?

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.

What is restrict in AngularJS directive?

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.


2 Answers

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> 
like image 100
L105 Avatar answered Oct 14 '22 17:10

L105


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.

like image 24
plong0 Avatar answered Oct 14 '22 16:10

plong0