简体   繁体   中英

How to access angular $scope controller in directive link?

I want to access $scope in controller from my directive link. It failed and threw an error. Thanks for your help.

The error is type error: scope.something is undefined .

HTML

<div ng-controller="myController">
  show me something {{ something }}
  <!-- this is a canvas -->
  <my-directive></my-directive>
</div>

JS

angular.module('fooBar',[]).controller(myController, ['$scope', function($scope) {
   // this is the something
   $scope.something = false;
}]).directive(myDirective, function(){
  return {
    template: '<canvas width='500px' height='500px'></canvas>',
    link: function(scope, el, attr) {
      //how to access that 'something'
      var bah = scope.something;
    }
  };
});

UPDATE Really thanks to you all. especially to u @immirza

im so sorry i cant reply u one by one. it just add $parent

//how to access that 'something'
var bah = scope.$parent.something

Did you try to set the "scope" option to "false" in the directive declaration? With this option, the scope of the directive must be the same as the controller's scope.

change to this...

angular.module('fooBar',[]).controller(myController, ['$scope', function($scope) {
   // this is the something
   $scope.something = false;
}]).directive(myDirective, function(){
  return {
    template: '<canvas width='500px' height='500px'></canvas>',
    link: function(scope, el, attr) {
      //how to access that 'something'
      var bah = $scope.something;//changed from scope.something to $scope.something 
    }
  };
});

If I understand your question correctly you want to have a directive that:

1/ Does not have an isolated scope (so you can access parent scope and interact, with it)

2/ You want to share some scope properties with your controller.

So solution is:

1/ @jkoestinger answer,

2/ using directive attributes and scope options object.

But for me you should spend some time here: https://docs.angularjs.org/guide/directive

Your code will work as you are expecting. This problem is some type errors are there in your code.

Please use

HTML

<div ng-controller="myController">
      show me something {{ something }}
      <!-- this is a canvas -->
      <my-directive></my-directive>
</div>

Angular

angular.module('fooBar',[])
  .controller('myController', ['$scope', function($scope) {
    // this is the something
    $scope.something = false;
  }])
  .directive('myDirective', function(){
    return {
      template: '<canvas width="500px" height="500px"></canvas>',
      link: function(scope, el, attr) {
        //how to access that 'something'
        var bah = scope.something;
        console.log(bah)
      }
    };
  });

Please refer fiddle

Explaination

The directive has no scope of itself unless specified. It will have scope to that of the parent. In This case ' scope of myDirective ' is same as scope of myController . This is because we can access scope.something in directive scope .

Error in your code

  1. Directive and controller name should be in quotes. ie( 'myDirective' not myDirective )
  2. Quotes inside quotes should be seperated.

    '<canvas width="500px" height="500px"></canvas>' //correct

     `'<canvas width='500px' height='500px'></canvas>'` `//incorrect` 

scope.something is undefined because the directives linking function is called before the controller is invoked. You need to use $watch .

angular.module('fooBar',[])
   .controller('myController', ['$scope', function($scope) {
       // this is the something
       $scope.something = false;
}]);


angular.module('fooBar').directive('myDirective', function(){
  return {
    template: '<canvas width='500px' height='500px'></canvas>',
    link: function(scope, el, attr) {
        var blah;
        scope.$watch("something", function (value) {
            blah = value;
        });
     }
  };
});

FYI, the scope is parent to directive so you need access as parent scope. Try following and it should work.

Also, the best way to know why it throw not defined error... put a breakpoint to the line, mouse over to $scope and and see all available items to scope.

angular.module('fooBar',[]).controller(myController, ['$scope', function($scope) {
   // this is the something
   $scope.something = false;
}]).directive(myDirective, function(){
  return {
    template: '<canvas width='500px' height='500px'></canvas>',
    link: function(scope, el, attr) {
      //how to access that 'something'
      var bah = scope.$parent.something; // added parent.
    }
  };
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM