Search code examples
angularjstypescriptgulpyeomanyeoman-generator

How to define a directive in gulp-angular-generator using typescript


I'm using the Yeoman generator gulp-angular-generator to create an Angular 1.3 project using Typescript. The seed project shows how to create a controller but not a directive. Here is my failed attempt so far:

src/app/index.ts

/// <reference path="../../.tmp/typings/tsd.d.ts" />
/// <reference path="components/workspace/workspace.controller.ts" />
/// <reference path="components/dashboard/dashboard.directive.ts" />

module app {
  'use strict';

  angular.module('app', ['ngAnimate', 'ngCookies', 'ngTouch', 'ngSanitize', 'restangular', 'ngRoute', 'ui.bootstrap'])
    .controller('WorkspaceCtrl', WorkspaceCtrl)

    .config(function ($routeProvider: ng.route.IRouteProvider) {
      $routeProvider
        .when('/', {
          templateUrl: 'app/components/workspace/workspace.template.html',
          controller: 'WorkspaceCtrl',
          controllerAs: 'workspace'
        })
        .otherwise({
          redirectTo: '/'
        });
    });
}

src/app/components/workspace/workspace.controller.ts

module app {
  'use strict';

  export class WorkspaceCtrl {
    //some code..
  }
}

src/app/components/dashboard/dashboard.directive.ts

module app {
  'use strict';

  angular
    .module('app')
    .directive('dashboard', () => {
      return {
        restrict: 'E',
        controllerAs: 'dashboard',
        bindToController: true,
        scope: {},
        templateUrl: 'app/components/dashboard/dashboard.template.html',
        controller: DashboardCtrl
      };
    });

  class DashboardCtrl {
    //some code..
  }
}

When I try to run this code I got the following error on the browser console (Chrome):

Uncaught Error: [$injector:nomod] Module 'app' is not available! You either 
misspelled the module name or forgot to load it. If registering a module ensure 
that you specify the dependencies as the second argument.

Inspecting the browser source files, I realized that the directive file is being loaded before the index where the module definition is present.

I know I could define the entire directive inside index.ts the same way the controller is defined (as suggested by the gulp-generator), but that is not a good idea because the Directive Definition Objects (DDO) are usually large and once your app begins to grow it will become harder to maintain.

Is there a way to define a directive in a different file and instruct the generator to load the files in the proper order?


Solution

  • Try this

    module app {
      'use strict';
    
      export function dashboard(): ng.IDirective {
        return {
          restrict: 'E',
          controllerAs: 'dashboard',
          bindToController: true,
          scope: {},
          templateUrl: 'app/components/dashboard/dashboard.template.html',
          controller: DashboardCtrl
        };
      }
    }
    

    Read more about how to write directives in typescript here: http://blog.aaronholmes.net/writing-angularjs-directives-as-typescript-classes/