shreyansh
shreyansh

Reputation: 1687

not able to call a function defined in directive into my controller

(function () {
    'use strict';

    angular
        .module('app')
        .directive('documentList', documentList);

    documentList.$inject = ['$window'];

    function documentList($window) {
        var directive = {
            restrict: 'E',
            controller: controller,
            controllerAs: "dl",
            templateUrl: 'directives/document/document-list.html',
            transclude: false,
            scope: {
                productRef: "=",
                productSerialNumber: "=",
                title: "@",
                eid: "@"
            },
        };
        return directive;

        function controller($scope, $state, $element, documentService, ngProgressFactory, registrationService) {

            var self = this;
                self.goToDetailPage=goToDetailPage;
               function goToDetailPage(docId) {

                   return "a";
                }


})();


(function() {
    'use strict';

    angular
        .module('app')
        .controller('DetailCtrl', detailCtrl);

    // Implementation of controller 
    detailCtrl.$inject = ['$scope', '$state', '$stateParams', '$rootScope'];

    function detailCtrl($scope, $state, $stateParams, $rootScope) {
       var self=this; 
       //alert($stateParams.docId)
       self.a=$scope.dl.goToDetailPage();
    }

})();

Above is the code in my directive and I have a controller where I want to call goToDetailPage function . But when I am trying to access it through var a=$scope.goToDetailPage() , I am getting error in console. Not able to rectify. Any help is appreciated!!! Thanks

 //DetailPage
        .state('app.sr.detail', {
            name: 'detail',
            url: '/detail',
            templateUrl: 'views/detail/detail1.html',
            controller: 'DetailCtrl',
            controllerAs: 'vm'
        })

Upvotes: 0

Views: 87

Answers (3)

Narain Mittal
Narain Mittal

Reputation: 1160

As it looks like from the snippets, DetailCtrl is parent of documentList directive. Functions in a child scope can't be accesses from parent controller. Consider defining goToDetailPage in DetailCtrl and inject that into the directive's scope using '&'

EDIT If you have something like this:

<div ng-controller="DetailCtrl">
    <document-list ...></document-list>
</div>

Then the controller DetailCtrl 's scope is the parent scope and the documentList directive's is the child. And since you are defining an isolate scope in documentList directive using scope: {...} parent and child scopes are different. And a method defined in the isolate scope can't be accessed directly in the parent scope using $scope.methodName().

You can however do the other way around, i.e. define the method in the DetailCtrl and inject into the directive's scope using this:

<div ng-controller="DetailCtrl">
    <document-list .... detail-page="goToDetailPage()"></document-list>
</div> 

And change your directive's scope to:

scope: {  ...,
         detailPage:'&'
        },

Now you can make a call to the function in the directive controller by calling detailPage()

See the Angular Guide

Hope that helps

Upvotes: 0

Jesse Carter
Jesse Carter

Reputation: 21147

A cool pattern you can use when you want to be able to invoke a function that lives in a directive but you need to be able to invoke from your controller is to pass in an object using two way binding and then extend that object with a function inside the directive. Inside your directive pass in an additional value:

scope: {
    productRef: "=",
    productSerialNumber: "=",
    title: "@",
    eid: "@",
    control: '=', // note that this is passed in using two way binding
}

Then extend that object inside your directive's controller by attaching a function to it:

// this is in your directive's controller
$scope.control.goToDetailPage = function() {
    // function logic
}

Now define the control object in your Controller and pass it into the directive. Because it is two way bound the function will be applied and available to be called in either scope.

// in your controller, assuming controller as syntax
var vm = this;
vm.control = {};

// somewhere later you can invoke it
vm.control.goToDetailPage();

Upvotes: 1

Chara
Chara

Reputation: 1075

Maybe try,

$scope.goToDetailPage = function (docId) {
      return "a";
}

Or, to make use of the "controller as" syntax,

var a = dl.goToDetailPage();

Upvotes: 0

Related Questions