AngularJS directive with method called from outside

梦想的初衷 提交于 2019-12-03 06:33:07

I found my issue.

From the angularJS documentation on directives I was looking into the transclude option since that states:

What does this transclude option do, exactly? transclude makes the contents of a directive with this option have access to the scope outside of the directive rather than inside.

I combined transclude=false with the controller function since that exposes the method, again from docs:

Savvy readers may be wondering what the difference is between link and controller. The basic difference is that controller can expose an API, and link functions can interact with controllers using require.

However what I missed completely was that I isolated scope within my directive. From docs:

What we want to be able to do is separate the scope inside a directive from the scope outside, and then map the outer scope to a directive's inner scope. We can do this by creating what we call an isolate scope. To do this, we can use a directive's scope option:

So even if you use transclude=false and the controller function you'll still fail to expose methods if you use isolated scope! Lesson learned!

While figuring out what went wrong I also made a fiddle for better understanding: http://jsfiddle.net/qyBEr/1/

html

<div ng-app="directiveScopeExample">

    <div ng-controller="Ctrl1">

        <p>see if we can trigger a method form the controller that exists in the directive.</p>

        <ul>
            <li><a href="#" ng-click="methodInController()">Method in Controller</a></li>
            <li><a href="#" ng-click="methodInDirective()">Method in Directive</a></li>
        </ul>

    <simple-directive/>
    </div>
</div>

javascript

angular.module('directiveScopeExample', [])

  .controller('Ctrl1', function Ctrl1($scope) {

      $scope.methodInController = function(){
          alert('Method in controller triggered');
    };

  })
  .directive('simpleDirective', function(){

      return {
      restrict: 'E',
      transclude: false,

      controller: function($scope){
          $scope.methodInDirective = function(){
              // call a method that is defined on scope but only within the directive, this is exposed beause defined within the link function on the $scope
              $scope.showMessage('Method in directive triggered');
          }
      }
      // this is the issue, creating a new scope prevents the controller to call the methods from the directive
      //, scope: {
      //  title: '@'
      //}
      , link: function(scope, element, attrs, tabsCtrl) {
         // view related code here
          scope.showMessage = function(message){
              alert(message);
          }
      },
      //templateUrl: 'some-template-here.html'
     };
  })  

Calling private methods inside directive's link function is very simple

   dropOffScope = $('#drop_off_date').scope();
   dropOffScope.setMinDate('11/10/2014');

where

   $('#drop_off_date') - jQuery function
   setMinDate() - private function inside directive

You can call directive function even from outer space.

By default the scope on directive is false meaning directive will use the parent's scope instead of creating a new one. And hence any function or model defined in the directive will be accessible in the parent scope. Check out this.

I think your problem can be solved as follows:

angular.module('directiveScopeExample', [])

  .controller('Ctrl1', function Ctrl1($scope) {

      $scope.methodInController = function(){
          alert('Method in controller triggered');
    };

  })
  .directive('simpleDirective', function(){

      return {
      restrict: 'E',
      scope: false,
      link: function(scope, element, attrs, tabsCtrl) {
         // view related code here
          scope.showMessage = function(message){
              alert(message);
          }
      },
      //templateUrl: 'some-template-here.html'
     };

This approach might be an issue in case you want to create reusable directives and you are maintaining some state/models in your directive scope. But since you are just creating functions without side-effects, you should be fine.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!