0

My code so far:

 .directive('ngSpreadsheet', function () {
      return {
          restrict: 'EA',
          scope: {
              curpart: '='
          },
          template: '<div id="dataTable" class="dataTable"></div>',
          controller: SpreadsheetController,
          link: function (scope, element, attrs) { 
              scope.$watch('curpart', function (val) {
                  console.log('curpart value changed, new value is: ' + val);
                  // here i want to call a function of the SpreadsheetController 
                  // or is there a better way, executing stuff when an attribute changed?
              });
          }

      }
  })


var SpreadsheetController = (function () {
  ...

  SpreadsheetController.prototype.curPartChanged = function () {
        console.debug('curPartChanged');
    };
})();
daniel
  • 34,281
  • 39
  • 104
  • 158
  • you should pass function name as attribute into directive using '&' feature in directive http://stackoverflow.com/questions/15991137/calling-method-of-parent-controller-from-a-directive-in-angularjs/15991525#15991525 – Ajay Beniwal Dec 18 '13 at 17:25
  • is there no better way? I think setting the connection in my html is bad style? – daniel Dec 18 '13 at 17:27

3 Answers3

1

If you want to get reference to your controller in your directive, then require your own directive. See: http://jsfiddle.net/7LnrZ/22/

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

mod.controller("SimpleCtrl", function ($scope) {
    var part = {};
    part.curpart = 1;

    $scope.part = part;

    $scope.increasePart = function () {
        part.curpart++;   
    }
});

var SpreadsheetController = function () {
    console.log("Instantiating SpreadsheetController");    
}

SpreadsheetController.prototype.curPartChanged = function () {
    console.log('curPartChanged');
}

mod.directive("ngSpreadsheet", function ($window) {
    return {
        restrict: 'EA',
        scope: {
            curpart: '='
        },
        require: "ngSpreadsheet",
        template: '<div id="dataTable" class="dataTable"></div>',
        controller: SpreadsheetController,
        link: function (scope, element, attrs, ctrl) { 
            scope.$watch('curpart', function (val) {
                console.log('curpart value changed, new value is: ' + val);
                ctrl.curPartChanged();
              });
          }
    }
});

Compiling order for a directive:

  • Directive Controller is called/created
  • Directive pre-link function is invoked
    • Child directive(s) of directive controller is created
    • Child directive(s) of directive pre-link is invoked
    • Child directive(s) of directive post-link is invoked
  • Directive post-link function is invoked
Patrick
  • 6,828
  • 3
  • 23
  • 31
1

The fourth parameter to a link function is the controller; I would recommend getting access that way.

link: function (scope, element, attrs, controller){
    //...
    controller.curPartChanged(...);
    //...
}

I can't seem to link directly to the anchor, but look in this doc for the section on LINK. You can search for "A controller instance if at least one directive on the element defines a controller" to find the exact section.

EDIT:

If you'd like to watch an attribute of a directive, I would consider the $observe function, which is very similar to $watch. Head to this SO post to learn more.

Community
  • 1
  • 1
Hylianpuffball
  • 1,553
  • 10
  • 13
0

Communication between a directive and the controller that hosts it should happen via an event call. scope.$emit will send such an event, while $scope.$on will catch events on the other side.

.directive('ngSpreadsheet', function () {
    return {
        restrict: 'EA',
        scope: {
            curpart: '='
        },
        template: '<div id="dataTable" class="dataTable"></div>',

        controller: function($scope){
            $scope.$on('curpart.change',function(data){
            console.log('curpart changed.. the new value is: ',data);
        }),

        link: function (scope, element, attrs) { 
            scope.$watch('curpart', function (evt,val) {
                console.log('curpart value changed, new value is: ' + val);
                scope.$emit('curpart.change',val);
            });
        }        
    }
});
Nemesarial
  • 487
  • 5
  • 12
  • I was under the impression that `$emit` and `$on` were for parent-child scope communication, not directive-controller communication. – Hylianpuffball Dec 18 '13 at 18:24
  • I see no reason why one cannot use events to effect communication between different elements within the same scope. In the case of a directive, there is a shared scope between the different parts of a directive - which makes events a great mechanism to communicate between the different parts of a directive. – Nemesarial Dec 19 '13 at 09:43