0

I try to create a function within an angular directive which should just change an object value.

It won't work with passing the variable directly to the function:

<body ng-controller="MainCtrl">
    <div test ng-click="changeVar(variable.value)">{{ variable.value }}</div>
</body> 

app.directive('test', [function(){
    return {
        link: function(scope, elem, attrs) {
          scope.variable = {
            value : "bla"
          }; 
          scope.changeVar = function(value) {
            value = "hhuhu"
          };
        }
    }
}]);

But passing the parent object does:

<body ng-controller="MainCtrl">
    <div test ng-click="changeObj(variable)">{{ variable.value }}</div>
</body>


app.directive('test', [function(){
    return {
        link: function(scope, elem, attrs) {
          scope.variable = {
            value : "bla"
          }; 
          scope.changeObj = function(obj) {
            obj.value = "hhuhu"
          };
        }
    }
}]);

Why do I have to pass the parent Object to the function to overwrite the value, and cannot pass the value directly to overwrite it? Am I missing something?

user3301565
  • 402
  • 5
  • 15
  • 1
    That's how javascript works. Check for example this question: http://stackoverflow.com/questions/13104494/does-javascript-pass-by-reference – apieceofbart May 19 '16 at 19:19

1 Answers1

3

I think what you are missing here is the notion of scopes in angularjs and how they are passed.

when you declare your directive like this:

app.directive('parent', [function(){
    return {
        controller: function($scope) {
        $scope.variable = {};
        // init
        $scope.variable.value = "foo";

        }
    }
}]);


app.directive('child', [function(){
    return {
        controller: function($scope) {

          // here you are directly using the parent's scope
          // so you can access $scope.variable directly 
          // without sending it in the function
          $scope.changeObj = function(replacement) {
            $scope.variable.value = replacement ;
          };
        }
    }
}]);

you are basically telling angular to use the parent scope as scope, because you are not defining a special scope for your directive.

(btw, this kind of operations:

      scope.changeObj = function(obj) {
        obj.value = "hhuhu"
      };

should not be in the link function but in the controller, it looks like controller logic to me : )

The second thing you can do is send the variable through a parameter to the child scope, as follows:

app.directive('parent', [function(){
    return {
        controller: function($scope) {
        $scope.variable = {};
        // init
        $scope.variable.value = "foo";

        }
    }
}]);


app.directive('child', [function(){
    return {
        scope:{myVariable: '='},
        controller: function($scope) {

          // here you are directly using the child's scope
          // but since you have defined double binding,
          // changing this in the child will also update the parent
          $scope.changeObj = function(replacement) {
            $scope.myVariable.value = replacement ;
          };
        }
    }
}]);


<body ng-controller="MainCtrl">
    <div test my-variable="variable" ng-click="changeObj('some text')">{{ variable.value }}</div>
</body>

I hope it's clear now

MayK
  • 1,269
  • 1
  • 10
  • 24