0

I neeed to pass a value from this part of the code in my directive to a controller, but not sure how to achieve that:

       if (!scope.multiple) {
          scope.model = value;
          console.log(scope.model);
          return;
        }

I get the value in the console.log, I just don't know how to pass it to the controller. This is the complete directive:

angular.module('quiz.directives')
.directive('fancySelect', function($rootScope, $timeout) {
  return {
    restrict: 'E',
    templateUrl: 'templates/directives/fancySelect.html',
    scope: {
      title: '@',
      model: '=',
      options: '=',
      multiple: '=',
      enable: '=',
      onChange: '&',
      class: '@'
    },
    link: function(scope) {
      scope.showOptions = false;
      scope.displayValues = [];

      scope.$watch('enable', function(enable) {
        if (!enable && scope.showOptions) {
          scope.toggleShowOptions(false);
        }
      });

      scope.toggleShowOptions = function(show) {
        if (!scope.enable) {
          return;
        }

        if (show === undefined) {
          show = !scope.showOptions;
        }

        if (show) {
          $rootScope.$broadcast('fancySelect:hideAll');
        }

        $timeout(function() {
          scope.showOptions = show;
        });
      };

      scope.toggleValue = function(value) {
        if (!value) {
          return;
        }

        if (!scope.multiple) {
          scope.model = value;
          console.log(scope.model);
          return;
        }

        var index = scope.model.indexOf(value);
        if (index >= 0) {
          scope.model.splice(index, 1);
        }
        else {
          scope.model.push(value);
        }

        if (scope.onChange) {
          scope.onChange();
        }
      };

      scope.getDisplayValues = function() {
        if (!scope.options || !scope.model) {
          return [];
        }

        if (!scope.multiple && scope.model) {
          return scope.options.filter(function(opt) {
            return opt.id == scope.model;
          });
        }

        return scope.options.filter(function(opt) {
          return scope.model.indexOf(opt.id) >= 0;
        });
      };

      $rootScope.$on('fancySelect:hideAll', function() {
        scope.showOptions = false;
      });
    }
  };
});

Updated

I tried to do as suggested in the answers by @Zidane and defining my object first in the controller like this:

$scope.year = {};

var saveUser = function(user) {
   $scope.profilePromise = UserService.save(user);
console.log($scope.year);

This is the template:

<fancy-select
            title="Klassetrinn"
            model="year"
            options="years"
            enable="true"
            on-change="onChangeYears()"
            active="yearsActive"
            name="playerYear"
            form-name="registerForm"
          >
          </fancy-select>

But I got an empty object in that case.

When I define my objects like this I get the right value in the controller but in the view the title is not being displayed anymore:

$scope.search = {
    years: []
  };

var saveUser = function(user) {
    $scope.profilePromise = UserService.save(user);
console.log($scope.search.years);

<fancy-select
            title="Klassetrinn"
            model="search.years"
            options="years"
            enable="true"
            on-change="onChangeYears()"
            active="yearsActive"
            name="playerYear"
            form-name="registerForm"
          >
          </fancy-select>
1
  • Not sure that completely understand your question, do you want to bind value to ng-model? Commented Sep 21, 2016 at 15:35

2 Answers 2

1

As you defined an isolated scope for your directive like this

scope: {
      ...
      model: '=',
      ...
    },

you give your directive a reference to an object on your controller scope. Declaring the directive like <fancy-select model="myModel" ....></fancy-select> you pass your directive a reference to scope.myModel on your controller. When you modify a property on the scope.model object in your directive you automatically modify the same property on the scope.myModel object in your controller.

So you have to do

myApp.controller('myController', function($scope) {
  ...
  $scope.myModel = {};
  ...
}

in your controller and in your directive just do

if (!scope.multiple) {
  scope.model.value = value;
  return;
}

Then you can get the value in your controller via $scope.myModel.value.

For clarification: You have to define an object on your controller and pass the directive the reference for this object so that the directive can follow the reference and doesn't mask it. If you did in your directive scope.model = 33 then you would just mask the reference passed to it from the controller, which means scope.model wouldn't point to the object on the controller anymore. When you do scope.model.value = 33 then you actually follow the object reference and modify the object on the controller scope.

Sign up to request clarification or add additional context in comments.

Comments

0

you can use services or factories to share data between your angular application parts, for example

    angular.module('myapp').factory('myDataSharing', myDataSharing);

function myDataSharing() {


    var sharedData = {
        fieldOne: ''
    };

    return {
        setData: setData,
        getData: getData,
    };


    function setData(dataFieldValue) {
        sharedData.fieldOne = dataFieldValue;
    };


    function getData() {
        sharedData.fieldOne
    };


    directive:
        myDataSharing.setData(dataValue);

    controller:
angular.module('myapp').controller('myController' ['myDataSharing'], function(myDataSharing) {
            var myDataFromSharedService = myDataSharing.getData();
        }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.