0

I'm trying to call $scope function in AngularJS Directive in following way

JS

    var app = angular.module('app', []);
    app.controller('customDirEx', ['$scope', function ($scope) {
    $scope.users = [
        {
            name: 'ABC',
            rno: '100'
        },
        {
            name: 'DEF',
            rno: '200'
        }
    ];

    $scope.onChangeFoo = function() {
        console.log('test');
    }

    $scope.dataChange = function() {
        console.log('test abc', $scope);
        $scope.onInitEle();
    }

    $scope.dataChange();
}]);

app.directive('studentInfo', function(){
    var directive = {};

    directive.scope = {
        user: '=user',
        onInitEle: '='
    };
    directive.restrict = 'EA';
    directive.template = '<div>Name: {{user.name}}<br>R.NO: {{user.rno}}</div>';

    return directive;
});

HTML

<body ng-app="app">
        <div ng-controller="customDirEx">            
            <student-info ng-repeat="user in users" user="user" on-init-ele="onChangeFoo"></student-info>            
        </div>
    </body>

$scope.onInitEle is not a function - this is the error I'm getting

The purpose of calling onClickEle instead of onChangeFoo here is too reuse the JS at multiple places so that I can call onChangeBar when required.

Mahesh.D
  • 1,691
  • 2
  • 23
  • 49

2 Answers2

1

First you have to replace "onClickEle: '='" with "onClickEle: '&'" The use of & means you are passing reference.

The second mistake is you didn't call it from your template. So, I have changed your template code as:

directive.template = '<div ng-click="onClickEle()"> Name: {{user.name}}<br>R.NO: {{user.rno}}</div>';

The third mistake is: you are calling $scope.onClickEle(); in controller, however onClickEle() not defined in controller, its under directive. So, controller unable to find the method.

The forth mistake is you are passing on-click-ele="onChangeFoo" in the direcive, the correct syntax will be:

on-click-ele="onChangeFoo()"

The working updated code given below:

var app = angular.module('app', []);
    app.controller('customDirEx', ['$scope', function ($scope) {
    $scope.users = [
        {
            name: 'ABC',
            rno: '100'
        },
        {
            name: 'DEF',
            rno: '200'
        }
    ];

    $scope.onChangeFoo = function() {
        console.log('test....');
    }

    $scope.dataChange = function() {
        console.log('test abc', $scope);
        //$scope.onClickEle();
    }

    $scope.dataChange();
}]);

app.directive('studentInfo', function(){
    var directive = {};

    directive.scope = {
        user: '=user',
        onClickEle: '&'
    };
    directive.restrict = 'EA';
    directive.template = '<div ng-click="onClickEle()"> Name: {{user.name}}<br>R.NO: {{user.rno}}</div>';

    return directive;
});
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="app">
        <div ng-controller="customDirEx">            
            <student-info ng-repeat="user in users" user="user" on-click-ele="onChangeFoo()"></student-info>            
        </div>
</body>
</html>
I. Ahmed
  • 2,438
  • 1
  • 12
  • 29
  • @Ahmed thanks for your efforts but it doesn't fulfill my requirements. I think you had confused with 'onClickEle()', sorry for that. I had replaced 'onClickEle()' with 'onInitEle()', I think it makes sense now. – Mahesh.D Feb 16 '18 at 05:19
  • @Mahesh.D, you cannot call directive function from controller. Directive can call the controller function, if you pass using & attribute, its point number 3. – I. Ahmed Feb 16 '18 at 05:30
  • @Ahmed if possible can you check my answer – Mahesh.D Feb 16 '18 at 06:15
1

Somehow I can manage this by creating separate controller for directive but don't know the theory behind, it would be very helpful if someone explains clearly.

JS

var app = angular.module('app', []);
app.controller('customDirEx', ['$scope', function ($scope) {
    $scope.users = [
        {
            name: 'ABC',
            rno: '100'
        },
        {
            name: 'DEF',
            rno: '200'
        }
    ];

    $scope.onChangeFoo = function() {
        console.log('test');
    }        
}]);

app.controller('StudentCtrl', ['$scope', function($scope){
    $scope.onInitEle();    
}]);

app.directive('studentInfo', function(){
    var directive = {};

    directive.scope = {
        user: '=user',
        onInitEle: '='
    };
    directive.restrict = 'EA';
    directive.template = '<div>Name: {{user.name}}<br>R.NO: {{user.rno}}</div>';
    directive.controller = 'StudentCtrl';

    return directive;
});

HTML

<body ng-app="app">
     <div ng-controller="customDirEx">            
            <student-info ng-repeat="user in users" user="user" on-init-ele="onChangeFoo"></student-info>            
     </div>
</body>

Working JSFiddle

Mahesh.D
  • 1,691
  • 2
  • 23
  • 49