Non
Non

Reputation: 8589

How to call a directive from a controller?

I am using DOM manipulation in a controller which I know it is not correct!

But, I need to know how to create a directive and then call it from a controller

here is the controller where I am doing the DOM manipulation

$scope.myPopover = $popover(angular.element('#betConf'), { //<--
  title: 'Bet Confirmation',
  template: 'views/betConfirmModal.html',
  html: true,
  autoClose: true,
  placement: 'bottom',
  trigger: 'manual',
  animation: 'fx-bounce-right',
  scope: $scope
});

and I am calling it this way

$scope.myPopover.show();

so, what should I do to make a directive, then call it in that controller without putting the directive directly in the DOM ?

EDIT TO EXPLAIN BETTER

the function $scope.myPopover is in the same controller I am calling $scope.myPopover.show();,

$scope.placeStraightBet = function(slip) {
  $scope.betId = '';
  var winValue = parseFloat(slip.risk, 10),
    riskValue = parseFloat(slip.win, 10),
    riskWin;
  // HERE CALL THE DIRECTIVE
  $scope.myPopover.show();
}

all I need is to create a directive, and call it in this controller, something like:

$scope.placeStraightBet = function(slip) {
  $scope.betId = '';
  var winValue = parseFloat(slip.risk, 10),
    riskValue = parseFloat(slip.win, 10),
    riskWin;
  // HERE CALL THE DIRECTIVE
  myDirective();
}

or:

$scope.myPopover = $popover(myElementDirective, {
  title: 'Bet Confirmation',
  template: 'views/betConfirmModal.html',
  html: true,
  autoClose: true,
  placement: 'bottom',
  trigger: 'manual',
  animation: 'fx-bounce-right',
  scope: $scope
});

all I want is avoid the usage of the DOM in the controller.

Upvotes: 0

Views: 858

Answers (3)

yvesmancera
yvesmancera

Reputation: 2925

You could create a directive with a "show" attribute, and set a watcher for when this property changes, like this:

angular.module('yourAppName')
  .directive('myPopover', function () {
    return {
      restrict: 'EA',
      scope: {
        show: '=',
      },
      link: function postLink($scope, element) {

        $scope.$watch('show', function(newVal, oldVal) {
          if(newVal && newVal !== oldVal) {
              $popover(element, { 
                 title: 'Bet Confirmation',
                 template: 'views/betConfirmModal.html',
                 html: true,
                 autoClose: true,
                 placement: 'bottom',
                 trigger: 'manual',
                 animation: 'fx-bounce-right',
                 scope: $scope.$parent
              }).show();

          }
        });            
      }
    };
  });

Your view would look something like this:

<my-popover show="showPopover"></my-popover>

And from your controller you show it by setting $scope.showPopover to true:

$scope.placeStraightBet = function(slip) {
  $scope.betId = '';
  var winValue = parseFloat(slip.risk, 10),
    riskValue = parseFloat(slip.win, 10),
    riskWin;
  // HERE CALL THE DIRECTIVE
  $scope.showPopover = true;
}

Upvotes: 1

Fabritzio Villegas
Fabritzio Villegas

Reputation: 93

Taking some of the answer of Jack Shultz, Creating a directive looks like this:

angular.module('bululu').directive('movement', function( $timeout, $interval) {
return {
    restrict: 'A',
    scope : {},
    link: function( scope, element, attrs ) {
      scope.elementsArray = ['facebook', 'linkedin', 'twitter', 'googleplus', 'mail', 'pinterest', 'behance', 'wordpress'];


      scope.moveElements = function() {
        $timeout(function(){
          for (var i = 0; i < scope.elementsArray.length; i++ ) {
            var top = Math.floor( ( Math.random() * 100 ) + 1 );
            var left = Math.floor( ( Math.random() * 100 ) + 1 );
            var target = document.getElementById(scope.elementsArray[i]);
            scope.element = angular.element(target);
            scope.element.css({
              'top': top + '%',
              'left': left + '%'
            });
          }
        }, 1000);
      };

      scope.moveElements();

      $interval( function() {
        scope.moveElements();
      }, 6000);

    },
 };

});

The restrict value defines how to "call" a directive, as stated in the Directive Documentation: The restrict option is typically set to:

'A' - only matches attribute name

<div movement></div>

'E' - only matches element name

<movement></movement>

'C' - only matches class name

<div class="movement"></div>

If you create an isolated scope, then every DOM element inside the directive div will use the scope.

<div movement>
    <button>Click here</button>
</div>

EDIT: Setting the scope attribute of the directive as false will share the scope with the controller, functions and variables could be shared this way.

Upvotes: 1

Jack Shultz
Jack Shultz

Reputation: 2091

This is an example of what directive might look like

angular.module('app.module', [])
.directive('myElementDirective', function() {
  return {
    restrict: 'A',
    title: 'Bet Confirmation',
    template: 'views/betConfirmModal.html',
    html: true,
    autoClose: true,
    placement: 'bottom',
    trigger: 'manual',
    animation: 'fx-bounce-right',
    scope: $scope
  };
});

Then in your html template you can assign this directive as an attribute

<div my-element-directive></div>

Upvotes: 0

Related Questions