0

I am trying to call a controller function from my directive, but it kept saying "my function is not defined". I am not familiar with angularJs directive. I tried to use link:function in my directive, but I really cannot figure it out. Please help.. thank you :-)

html:

<body ng-app="myApp">
    <div ng-controller="myCtrl">
      <button class="btn" ng-click="changeDataObj()">Change Data Object</button>
      <div my-Tree list="list" >

      </div>            
    </div>
  </body>

js:

angular.module('myApp', [])
    .controller('myCtrl', myCtrl)
    .directive('myTree', ['$compile', myTree]);

function myCtrl($timeout, $scope) {        
    $scope.reset = true;
    $scope.list = [
        {
            name: 'Laptop',
            children: [
                {
                    name: 'Apple',
                    children: [
                        { name: 'Macbook Air' },
                        { name: 'Macbook Pro' }
                    ]
                },
                {
                    name: 'Microsoft',
                    children: [
                        { name: 'Surface Pro' }
                    ]
                }
            ]
        },
        {
            name: 'Desktop',
            children: [
                { name: 'Dell' }
            ]
        }
    ];

    $scope.selectANode = function (name) {
        alert(name);
    }       
}
function myTree($compile) {
    return {
        restrict: 'EA',
        scope: {
            list: '='
        },
        compile: function (tElem) {
            return {
                post: function (scope, iElem, iAttrs) {

                    var htmlString = [''];

                    addChildren(htmlString, scope.list, true);

                    function addChildren(htmlString, array, first) {    
                        if (!angular.isArray(array)) return;

                        if (first) { // root level parent must always be display:block
                            htmlString[0] += '<ul>';
                        } else {
                            htmlString[0] += '<ul style="display:none;">';
                        }

                        for (var i = 0; i < array.length; i++) {
                            htmlString[0] += '<li><span ng-click="selectANode(\'' + array[i].name + '\')">' + array[i].name + '</span><i class="navFinder__toggleBtn fa fa-folder-o"></i>';
                            addChildren(htmlString, array[i].children);
                            htmlString[0] += '</li>';
                        }
                        htmlString[0] += '</ul>';
                    }

                    var compiledContents = $compile(htmlString[0]);
                    compiledContents(scope, function (clone) {
                        iElem.append(clone);
                    })

                    iElem.find('i').on('click', function (event) {
                        event.target.className = (event.target.className == 'fa fa-folder-open-o navFinder__toggleBtn') ? 'fa fa-folder-o navFinder__toggleBtn' : 'fa fa-folder-open-o navFinder__toggleBtn'; // change icon
                        event.target.nextSibling.style.display = (event.target.nextSibling.style.display == 'none') ? 'block' : 'none'; // expand and collapse
                    });    
                }
            };
        }
    };
}
1
  • I think you are missing the [] syntax for the dep injection of the controller. You should have written below instead .controller('myCtrl', ['$timeout', '$scope', myCtrl]) Commented Apr 10, 2020 at 16:41

1 Answer 1

1

Your method on ng-click should stay in compile->post

 scope.selectANode = function (name) {
        alert(name);
 }

Plunker 1


But if you want to call the controller's method, you need to add additional code to bind it:

 scope: {
            list: '=',
            selectNode: '&'
        },

// ...
scope.selectANode = function (name) {
    scope.selectNode({data: name});
}  

and your HTML:

<div my-Tree list="list" select-node="selectANode(data)">

Plunker 2

Enjoy :)

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.