Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS Link function not being called

Tags:

angularjs

For some reason my link function inside my directive is not being called. I can see that my directive is called with a console.log but not the link function. Also don't mind the controller parameter I will be using that with my parent directive. I have also tried restrict: 'E' with no luck as well. I am not using it for this example. Not sure what is causing it to skip link. Any thoughts?

module FormTest {
    angular
        .module('FormTest') //Gets the FormTest Module
        .directive('jiTab', function () {
            console.log('directive was hit');
            function linkFn(scope, ele, attrs, controller) {
                console.log('Link is called');
            };
            return {
                require: '^ji-Tabset',
                restrict: 'C',
                transclude: true,
                link: linkFn
            }
        });
 }

HTML

<ji-form name="Main Form">  
    <ji-tabset name="Tabs">  
        <ji-tab tab-name="General"></ji-tab>  
        <ji-tab tab-name="Stats"></ji-tab>  
    </ji-tabset>  
</ji-form>

Parent directive

module FormTest {
    angular
        .module('FormTest') //Gets the FormTest Module
        .directive('jiTabset', function () {
            return {
                restrict: 'E',
                transclude: true,
                replace: true,
                templateUrl: 'FormTest/views/ji-Tabset.html',
                controller: function ($scope) {
                    var tabPanelItems = $scope.tabPanelItems = [];
                    $scope.tabSettings = {
                        dataSource: tabPanelItems
                    }
                }
            };
        });
}
like image 898
Tim Avatar asked Aug 26 '15 14:08

Tim


2 Answers

module FormTest {
    angular
        .module('FormTest') //Gets the FormTest Module
        .directive('jiTab', function () {
            console.log('directive was hit');
            function linkFn(scope, ele, attrs, controller) {
                console.log('Link is called');
            };
            return {
                require: '^ji-Tabset', //<-- this must be `^jiTabset` read mistake 1
                restrict: 'C', //<-- this must be `E` which stands for element, (jiTab) C is for class, read mistake 2
                transclude: true,
                link: linkFn
            }
        });
 }

From docs

Mistake 1

Normalization Angular normalizes an element's tag and attribute name to determine which elements match which directives. We typically refer to directives by their case-sensitive camelCase normalized name (e.g. ngModel). However, since HTML is case-insensitive, we refer to directives in the DOM by lower-case forms, typically using dash-delimited attributes on DOM elements (e.g. ng-model).

The normalization process is as follows:

  • Strip x- and data- from the front of the element/attributes.
  • Convert the :, -, or _-delimited name to camelCase.

Mistake 2

The restrict option is typically set to:

  • 'A' - only matches attribute name
  • 'E' - only matches element name
  • 'C' - only matches class name These restrictions can all be combined as needed:

'AEC' - matches either attribute or element or class name

Mistake 3

You dont have ng-transclude attribute in your jiTabset directive, make sure you have it there 'FormTest/views/ji-Tabset.html'

Worknig demo

Open browser console

angular.module('FormTest', []);
angular.module('FormTest') //Gets the FormTest Module
        .directive('jiTabset', function () {
            return {
                restrict: 'E',
                transclude: true,
                replace: true,
                template: '<div>ji-tabset<div ng-transclude></div></div>',
                controller: function ($scope) {
                    var tabPanelItems = $scope.tabPanelItems = [];
                    $scope.tabSettings = {
                        dataSource: tabPanelItems
                    }
                }
            };
        });
angular.module('FormTest') //Gets the FormTest Module
        .directive('jiTab', function () {
            function linkFn(scope, ele, attrs, controller) {
                console.log('Link is called');
            };
            return {
                require: '^jiTabset',
                restrict: 'E',
                transclude: true,
                link: linkFn
            }
        });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"></script>
<div ng-app="FormTest">
  <ji-form name="Main Form">  
    <ji-tabset name="Tabs">  
        <ji-tab tab-name="General"></ji-tab>  
        <ji-tab tab-name="Stats"></ji-tab>  
    </ji-tabset>  
</ji-form>
</div>
like image 162
Medet Tleukabiluly Avatar answered Oct 06 '22 01:10

Medet Tleukabiluly


By assigning a variable to a function and calling it where ever you want by its variable name,

angular
.module('FormTest') //Gets the FormTest Module
.directive('jiTab', function () {
 var linkFn = function (scope, ele, attrs, controller) {
    console.log('Link is called');
};
return {
    restrict: 'C',
    transclude: true,
    link: linkFn
}
});

by this way i think you can achieve i hope.

like image 34
Alhuck Avatar answered Oct 06 '22 01:10

Alhuck