Friday, 14 April 2017

Create a angular 1.5 directive in Typescript

In this post we are going to see how to create a angular 1.5 directive in Typescript,  create the properties of return object as properties of diretive class, implements ng.IDirective in the directive class,

Then create a factory function which implements ng.IDirectiveFactory which returns the new instance of directive , where we inject the dependencies for Directive.

For example we are creating a star Directive which will render the star


module app.directives {

    export interface IStarController {
        getData(): void;
        updateStars(): void;
    }

    export interface IStarScope extends ng.IScope {
        toggle(index: number): void;
        readonly: string;
        ratingValue: number;
        onRatingChanged(input: Object): void;
        stars: any[];
        max: number;
        starSize: number;
    }

    class StarController implements IStarController {

        static $inject = ['$scope'];

        constructor(private $scope: IStarScope) {
                   
        }

        public getData() {
            console.log('scope'); 
            console.log(this.$scope);
        }

       
        updateStars = (): void => {
            this.$scope.stars = [];
            for (var i = 0; i < this.$scope.max; i++) {
                this.$scope.stars.push({ filled: i < this.$scope.ratingValue });
            }
        }


    }

    
    class StarDirective implements ng.IDirective {

        constructor(private logfactory: app.logfactory.ILOGFactory) {

        }

        public controller:any= StarController;
        public restrict: string = 'EA';
        public template: string = '<ul class="rating">' +
        '<li ng-repeat="star in stars" ng-class="star" ng-click="toggle($index)">' +
                                          '\u2605' +
                                    '</li>' +
                                  '</ul>';
        public scope: any = {
            ratingValue: '=',
            max: '=',
            readonly: '@',
            starSize: '=',
            onRatingChanged: '&'
        }
        public link: ng.IDirectiveLinkFn = (scope: app.directives.IStarScope, 
               elem: ng.IAugmentedJQuery, attr: ng.IAttributes, 
               ctrl: app.directives.IStarController) => {


            let logging = this.logfactory;

            elem.css('font-size', scope.starSize+'px');

            scope.toggle = function (index) {
                if (scope.readonly && scope.readonly === 'true') {
                    return;
                }
                scope.ratingValue = index + 1;

                scope.onRatingChanged({ rating: index + 1 });
                logging.writeWarn({ rating: index + 1 }.rating.toString());
            };
           
            scope.$watch('ratingValue', function (oldval, newval) {
                if (newval) {
                    ctrl.updateStars();
                }
            })           

        }

        public static factory(): ng.IDirectiveFactory {
       let directive: ng.IDirectiveFactory = (logfactory: app.logfactory.ILOGFactory) 
               => new StarDirective(logfactory);
            directive.$inject = ['logfactory'];
            return directive;
        }

    }

    angular.module('myapp').directive('starRating', StarDirective.factory());




CSS:

.rating {
    color: #a9a9a9;
    margin: 0;
    padding: 0;
}

ul.rating {
    display: inline-block;
}

.rating li {
    list-style-type: none;
    display: inline-block;
    padding: 1px;
    text-align: center;
    font-weight: bold;
    cursor: pointer;
}

.rating .filled {
    color: red;
}










From this post you can learn how to create a directive in Typescript