Search code examples
javascriptangularjsangular-directive

AngularJS - call listener of directive on click and pass data to it


So, I was working with directives in AngularJS. What I want to achieve is that call the listener of the directive on the click of a button and pass it some data from the controller.

Here's my directive (example)

app.directive('graphVisualization', function() {
    var containerid = document.getElementById('left-graph-container');
    return {
        restrict: 'A',
        scope: {
          data: '=',
          val: '=',
        },
        link: function(scope, element, attrs) {
            scope.$watch('data', function(newVal, oldVal) {
                //listener code
            })
        }
    }

Here's my HTML

<div graph-visualization data="graphdata" val="stability">
</div>
<div>
    <input type="button" value="Call" ng-click="setData(6)" />
</div>

And here's my controller

app.controller('MainCtrl', ['$scope', function() {
    $scope.graphdata = ['time1', 'time2', 'time3'];
    $scope.setData() = function(val) {
        $scope.data = val;
        //now call the directive's listener code i.e. 'link' function and pass it '$scope.data'
    }
}])

So, I need to pass $scope.data from the controller to the directive and then run the code of the link function using that data. What I'm doing in the listener code is rendering a graph using D3 and I want to re-render that graph using the data sent each time I click the button. How do I go about this?


Solution

  • you are passing data="graphdata", why not data="data" ?

    from my experience with Angular I found that using child variables are more effective working with directives, neither with direct variables

    not:

    $scope.data = val;
    

    but:

    $scope.state = {};
    
    $scope.setData() = function(val) {
        $scope.state.data = val;
    }
    

    and pass state.data in html:

    <div graph-visualization data="state.data" val="stability"></div>
    

    you are not replacing instance of whole variable $scope.data, but just updating it properties, so watch in directive on 'data' will refer to the same instance.

    You got my idea :)