0

I recently started using bindToController in my angular directives and I had an issue with 'this'. In my controller method, how to I access properties of the class MultiSelect. 'this' in that context is referring to the $scope due to the controllerAs syntax which is expected, but now how do I access my searchService service?

/// <reference path="../../../../definitions/app.d.ts" />
module App.directives
{
    'use strict';

    class MultiSelect implements ng.IDirective 
    {
        restrict = 'E';
        templateUrl = 'directives/multi-select/multi-select.directive.html';
        scope = {};
        bindToController = {
            value: '='
        };
        controllerAs = 'multiSelect';

        constructor(private searchService: App.ISearchService) {

        }

        controller() 
        {
            console.log(this)
            // prints {value: undefined}
            // which matches bindToController

            this.searchService.get();
            // TypeError: Cannot read property 'get' of undefined
        }

        link = ($scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes) => {


        }

        static factory(): ng.IDirectiveFactory 
        {
            const directive = (searchService: App.ISearchService) => new MultiSelect(searchService);
            return directive;
        }
    }

    angular.module('App').directive('multiSelect', ['searchService', MultiSelect.factory()]);
}
Amrit Kahlon
  • 1,286
  • 1
  • 18
  • 38

2 Answers2

0

I recently started using bindToController in my angular directives

Don't. That changes the semantics from this to be different from what TypeScript infers.

basarat
  • 261,912
  • 58
  • 460
  • 511
  • But it allows us to separate the scope initialization as well as public api of the directive, from the dom manipulation which occurs in link - [SO](http://stackoverflow.com/questions/27771823/angularjs-should-i-convert-directives-linking-function-to-a-controller). I think I figured it out though – Amrit Kahlon Aug 01 '15 at 00:54
  • Maybe you're right, the method I tried doesn't make sense. Its just weird that they would encourage you to use bindToController to help in the migration to Angular 2, yet its not possible in typescript. The reason I'm using typescript is to get used to it now in getting ready for angular 2 http://www.effectiveui.com/blog/2015/04/20/learned-ng-conf-write-angularjs-migration-mind/ – Amrit Kahlon Aug 06 '15 at 01:11
0

This is how it is done according to Dan Wahlin. From the Angular in 20 Typescript project.

///<reference path="../../../tools/typings/tsd.d.ts" />
///<reference path="../../../tools/typings/typescriptApp.d.ts" />

module demoApp.directives {

    class FilterTextbox implements ng.IDirective {

        static instance() : ng.IDirective {
            return new FilterTextbox();
        }

        template = 'Search: <input type="text" ng-model="vm.filter" /> {{ vm.message }}';
        restrict = 'E';
        scope = {
            filter: '='
        };
        controller: ($scope: ng.IScope) => void;
        controllerAs = 'vm';
        bindToController = true;

        constructor() {
            this.controller = function ($scope: ng.IScope) {
                var vm = this;
                vm.message = 'Hello';

                $scope.$watch('vm.filter', (newVal, oldVal) => {
                    if (oldVal !== '' && newVal === '') {
                        vm.message = 'Please enter a value';
                    } else {
                        vm.message = '';
                    }
                });
            };
        }
    }

    angular.module('demoApp').directive('filterTextbox', FilterTextbox.instance);

}
Amrit Kahlon
  • 1,286
  • 1
  • 18
  • 38