0

I can't figure this one on my own. Maybe I'm missing something. I have a controller and a directive which creates its own scope.

Plunker link : http://run.plnkr.co/plunks/wFV7d2blZKEXUgHIOxYo/

Here is the controller code which just creates 3 variables and exposes a "change" function for each one :

var myApp = angular.module("myApp",[]);

myApp.controller('MainController', function ( $scope, $rootScope ) {
  $rootScope.showStuff = true;
  $scope.showStuff2 = true;
  $scope.showStuffObj = { stuff : true };

  $scope.changeStuff = function () {
    $rootScope.showStuff = false;
  }

  $scope.changeStuff2 = function () {
    $scope.showStuff2 = false;
  }

  $scope.changeStuff3 = function () {
    $scope.showStuffObj.stuff = false;
  }
});

Coming up next, the directive:

myApp.directive("mydirective", function () {
  return {
    scope : {
      showStuff : "=",
      showStuff2 : "=",
      showStuffObj : '='
    },
    restrict : "EA",
    template : "<h2>Running</h2>",
    link : function ( $scope ) {
      console.log("running directive", $scope);
      $scope.$watch("showStuff", function () {
        console.log($scope.showStuff);
      });

      $scope.$watch("showStuff2", function () {
        console.log($scope.showStuff2);
      });

      $scope.$watch("showStuffObj", function () {
        console.log($scope.showStuffObj);
      });
    }
  };
});

Why do I get this ?

console results

If the two way binding works, I should see the real values of the variables, not undefined. Why doesn't the watch update when I update the variables? This is very confusing.

Vlad Nicula
  • 3,577
  • 6
  • 32
  • 50
  • 1
    Your syntax while using camel case in angular in not correct http://stackoverflow.com/questions/15990122/passing-object-to-angularjs-directive-from-the-controller/15990397#15990397 – Ajay Beniwal Jun 17 '13 at 07:58
  • so variable thisString will be accessed like attr "this-string" ? – Vlad Nicula Jun 17 '13 at 08:12

1 Answers1

1

There are two problems:

As beniwal said, the attributes in the directives must be separated with dashes, while the local scope variables are in camelCase:

<mydirective show-stuff="showStuff" show-stuff2="showStuff2" show-stuff-obj="showStuffObj">

.

scope : {
  showStuff : "=",
  showStuff2 : "=",
  showStuffObj : "="
},

For watching to work In case of showStuffObj, you must a) deep-watch the object, or directly watch a property. Deep-watching is expensive, so only do it if it is really necessary:

Watching single property:

  $scope.$watch("showStuffObj.stuff", function () {
    console.log($scope.showStuffObj.stuff);
  });

Deep watch:

  $scope.$watch("localShowStuffObj", function () {
    console.log($scope.localShowStuffObj);
  }, true);

The third parameter of watch set to true turns on deep watching.

plnkr: http://plnkr.co/edit/sxfIK16kTffxr4Z1R80s?p=preview

Narretz
  • 4,769
  • 32
  • 40