I'm new to Angular JS and I am trying to create a custom directive that will be used as below:
<div linkedlist listcolumns="{{cashAccountsColumns}}"></div>
Corrps. controller will be:
$scope.cashAccountsColumns = [
{"field": "description", "title": "Description"},
{"field": "owner", "title":"Owner"},
{"field": "currentBalance", "title":"Current Balance" }
];
And the directive code is:
return {
restrict : 'EA',
transclude : false,
templateUrl : 'html/linkedlist.html',
scope: {
listcolumns: "@"
},
link : function(scope, element, attrs) {
}
}
template is:
<table class="box-table" width="100%">
<thead>
<tr>
<th scope="col" ng-repeat="column in listcolumns">
{{column.title}}
</th>
</tr>
</thead>
</table>
But this is not working. I'm not getting the value of column.title on screen instead too many rows as below are added to DOM:
<th ng-repeat="column in listcolumns" scope="col" class="ng-scope ng-binding"></th>
@AjayBeniwal's answer is correct, but I feel as though it could use some additional explanation.
As the Angular documentation points out (in the "Isolating the Scope of a Directive" section), the
scope
option is an object that contains a property for each isolate scope binding. We use it to separate (isolate) the scope inside a directive from the scope outside, and then map the outer scope to the directive's inner scope.The name of each property of the
scope
object corresponds to the directives isolate scope property. In the question's example, the only property of thescope
object islistcolumns
. Because of this, there must also be a corresponding attribute on the html creating the directive:The name of the
scope
property and the directive's attribute are not however required to have the same name. We can map these two values like this:-
For cases where the attribute name is the same as the value you want to bind inside the directive's scope, you can use this shorthand syntax:
-
Additionally, in this example the value of the directive's attribute must correspond to a property of the directive's outer scope. This is because the
=
in=shortName
uses bi-directional binding of attributes from the outer scope to the isolate scope, forcing the value of the directive's attribute to be evaluated as an expression. As this answer eloquently points out, if we instead want to pass a literal string, we can either use@
in place of=
, or sorround the directive's isolate scope property with both double and single quotes:OR
Passing an entire object with attribute will not work, you have to use dual way binding. Just change binding from
@
to=
and modify the HTML below to make it work:changes to directive code:
changes to template: