admin管理员组

文章数量:1202022

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?

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?

Share Improve this question asked Dec 24, 2012 at 14:13 Yair NevetYair Nevet 13k17 gold badges69 silver badges109 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 7

You are accessing scope[attrs.name] but the directive doesn't provide a value for the attribute name

There are 2 options:

  1. Change the directive to elm.text("hello, " + scope['name']); This is not a preferred way as it hard codes to a scope property name

  2. 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.

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.

You can access using scope. Look http://jsfiddle.net/rPUM5/

directives.directive("hello", function () {
    return function (scope, elm, attrs) {
        elm.text("hello, " + scope.name);
    };
});​

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

本文标签: javascriptCan39t access controller scope from directiveStack Overflow