Search code examples
javascriptangularjsangular-directive

How can i use controller object values in angular directive?


I have angular select on main page once user select value i want these object values in directive e.g $scope.selectedFileSize.value and $scope.selectedFileSize.size so i can further implement logic in directive. Any idea ?

main.html

<div class="col-md-3">
    <select class="form-control" ng-model="selectedFileSize" ng-options="item as item.value for item in FileSizeOptions" ng-change="onSizeChange()"><option value="">Select</option></select>
</div>

<progress-bar-custom message="event"></progress-bar-custom>

Controller.js

  $scope.onSizeChange = function(){
        $scope.maxMb = $scope.selectedFileSize.size;
        $scope.maxBytes = 3000;
        $scope.max = $scope.maxBytes;
        $scope.FileSizeString = $scope.selectedFileSize.value;
        console.log('FileSize',$scope.maxMb);
    }

directive.js

angular.module("App").directive('progressBarCustom', function() {
            return {
                restrict: 'E',
                scope: {
                    message: "="
                },
                templateUrl: '/view/partials/progressbar.html',
                controller: function($scope) {
                    var data = $scope.message;
                    var currentFileBytes = [];
                    var currentBytesSum;
                    $scope.maxBytes = 3000; // how to get these values from controller 
                    $scope.max = $scope.maxBytes;
                    $scope.FileSizeString = $scope.selectedFileSize.value; //How can i get these values from controller.

                    $scope.random = function(value) {
                        $scope.dynamic = value;
                        $scope.downloadPercentage = parseFloat((value / $scope.maxBytes) * 100).toFixed(0);
                        console.log('current value-dynamic', $scope.dynamic);
                    };

                }
            });

Solution

  • You can define them as bindings in your directive scope:

    scope: {
        message: "=",
        objToBind: "=" // add this one
    },
    

    And in HTML:

    <progress-bar-custom message="event" obj-to-bind="selectedFileSize"></progress-bar-custom>
    

    Then you could access it in your directive controller:

    $scope.FileSizeString = $scope.objToBind.value
    

    EDIT

    I guess you want to dynamically change $scope.FileSizeString when your select is changed, right? Then I think you need to $watch in directive, otherwise it's always the initial value, and you won't aware of the changes in the future.

    I don't know exactly how you implement your app, so I wrote a simple demo that demonstrate the key points:

    1. I moved your default select option into ng-options array, and instead use ng-init to set default option.
    2. I use $watch in directive to observe the binding's value change.

    var app = angular.module('myApp', [])
    
    app.controller('myCtrl', ['$scope', function($scope) {
      $scope.fileSizes = [
        {size: -1, value: 'Select'},
        {size: 1, value: '1MB'},
        {size: 2, value: '2MB'},
        {size: 3, value: '3MB'}
      ]
    
      $scope.onSizeChange = function() {
        console.log($scope.selected.size)
      }
    }])
    
    app.directive('myDirective', function() {
      return {
        restrict: 'E',
        scope: {
          selectedSize: '='
        },
        template: '<div style="font-family:monospace"><p><b>Your choice:</b> {{myChoice}}</p><p><b>Actual Choice:</b> {{selectedSize}}</p></div>',
        controller: function($scope) {
          $scope.myChoice = ''
          $scope.$watch('selectedSize', function (newVal, oldVal) {
            $scope.myChoice = (newVal && newVal.size !== -1) ? newVal.value : ''
          })
        }
      }
    })
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
    <div ng-app="myApp">
      <div ng-controller="myCtrl">
        <select ng-options="opt as opt.value for opt in fileSizes"
                ng-model="selected"
                ng-init="selected = fileSizes[0]"
                ng-change="onSizeChange()">
        </select>
        <my-directive selected-size="selected"></my-directive>
      </div>
    </div>