Reputation: 13013
This is my app config:
angular.module('myApp', ['myApp.directives', 'myApp.controllers', 'myApp.services']);
This is my controller:
angular.module('myApp.controllers', [])
.controller('MainCtrl', function ($scope) {
$scope.name = 'world';
});
This is my directive:
var directives = angular.module('myApp.directives', []);
directives.directive("hello", function () {
return function (scope, elm, attrs) {
elm.text("hello, " + scope[attrs.name]);
};
});
and this is my html:
<div ng-controller="MainCtrl">
<h1 hello></h1>
</div>
The is problem is that angular render the directive as:
hello, undefined
Instead of:
hello, world
What is wrong?
Upvotes: 11
Views: 14165
Reputation: 3118
You can access using scope
. Look http://jsfiddle.net/rPUM5/
directives.directive("hello", function () {
return function (scope, elm, attrs) {
elm.text("hello, " + scope.name);
};
});
Upvotes: 3
Reputation: 21577
I found another case:
if you are accessing a variable coming from a Ajax request body, then you have to WAIT until the variable is set.
e.g:
# in controller
$http.get('/preview').then( (response) ->
$scope.tabs = response.data.tabs
$scope.master_switch = '1'
console.info 'after get response in controller'
)
# in directive
directive('masterSwitch', ->
(scope, element, attrs) ->
alert 'in directive!' # will show before "after get response in controller"
console.info scope.master_switch # is undefined
setTimeout( -> console.info(scope.master_switch), 50) # => 1
Upvotes: 1
Reputation: 1706
You can do something that, as of writing this, appears to be undocumented in Angular (see Mark Rajcok's comment here: http://docs.angularjs.org/api/ng.$rootScope.Scope).
From within your directive:
scope.$parent.name
If you do a console.log(scope)
on the directive's scope
(from within the directive), you'll see these properties.
All this said, I don't know whether or not this is "proper" Angular convention, due to the fact that this is both undocumented, and I haven't found any other better documentation on how to access the controller that a directive sits within.
Upvotes: 6
Reputation: 23664
You are accessing scope[attrs.name]
but the directive doesn't provide a value for the attribute name
There are 2 options:
Change the directive to elm.text("hello, " + scope['name']);
This is not a preferred way as it hard codes to a scope property name
Change the html to <h1 hello name="name"></h1>
. This is better but I feel it uses a redundant attribute
I would suggest you change the directive to elm.text("hello, " + scope[attrs['hello']]);
Or even better elm.text("hello, " + scope.$eval(attrs['hello']));
this way you get the benefit of expressions as well(ex: <h1 hello="name|uppercase"></h1>
)
demo
This way the html would be <h1 hello="name"></h1>
Regarding the attrs parameter: it's nothing more than a map of strings taken from the attributes present on the dom element.
Upvotes: 7