AngularJS Typescript 路由
Posted
技术标签:
【中文标题】AngularJS Typescript 路由【英文标题】:AngularJS Typescript Routing 【发布时间】:2014-03-14 20:18:58 【问题描述】:我正在使用 following template 配置 AngularJS/Typescript Web 应用程序并收到以下错误。
The following error is appearing when I run the application:
0x800a139e - javascript runtime error: [$injector:modulerr] Failed to instantiate module app due to:
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.
我检查了this thread 并确保我确实引用了 angular-route.js
app.ts - Easier version to view + index.html
/// <reference path="./typings/angularjs/angular.d.ts" />
'use strict';
// Create and register modules
var modules = ['app.controllers','app.directives', 'app.filters', 'app.services'];
modules.forEach((module) => angular.module(module, []));
angular.module('app', modules);
// Url routing
angular.module('app').config(['$routeProvider',
function routes($routeProvider: ng.IRouteProvider)
$routeProvider
.when('/',
templateUrl: 'views/MyView.html',
controller: 'app.controllers.MyController'
)
.otherwise(
redirectTo: '/'
);
]);
module app
export module controllers
export module directives
export module filters
export module services
export interface IController
export interface IDirective
restrict: string;
link($scope: ng.IScope, element: JQuery, attrs: ng.IAttributes): any;
export interface IFilter
filter (input: any, ...args: any[]): any;
export interface IService
/**
* Register new controller.
*
* @param className
* @param services
*/
export function registerController (className: string, services = [])
var controller = 'app.controllers.' + className;
services.push(app.controllers[className]);
angular.module('app.controllers').controller(controller, services);
/**
* Register new filter.
*
* @param className
* @param services
*/
export function registerFilter (className: string, services = [])
var filter = className.toLowerCase();
services.push(() => (new app.filters[className]()).filter);
angular.module('app.filters').filter(filter, services);
/**
* Register new directive.
*
* @param className
* @param services
*/
export function registerDirective (className: string, services = [])
var directive = className[0].toLowerCase() + className.slice(1);
services.push(() => new app.directives[className]());
angular.module('app.directives').directive(directive, services);
/**
* Register new service.
*
* @param className
* @param services
*/
export function registerService (className: string, services = [])
var service = className[0].toLowerCase() + className.slice(1);
services.push(() => new app.services[className]());
angular.module('app.services').factory(service, services);
我是一个 TS/Angular 新手,因此我们将不胜感激。
谢谢
潜在重复:AngularJS + TypeScript: cannot inject $routeProvider
【问题讨论】:
您使用的是哪个版本的 Typescript?该模板很旧,并且在0.9.1.1
和 0.9.5
分支上都抛出了错误。
我相信我在 0.9.21
【参考方案1】:
您需要对该模板进行一些更改才能使其正常工作。
Full source here
首先确保您有正确的参考。包括对angular-route.d.ts
的引用
/// <reference path="./typings/angularjs/angular.d.ts" />
/// <reference path="./typings/angularjs/angular-route.d.ts" />
'use strict';
// Create and register modules
var modules = ['app.controllers','app.directives', 'app.filters', 'app.services'];
modules.forEach((module) => angular.module(module, []));
要使用$routeProvider
,你必须在你的模块中包含ngRoute
模块,但是因为我们不想用angular注册它,因为它已经存在,我们需要像这样推送模块:
// *** Push ngRoute or $routeProvider won't work ***
modules.push("ngRoute");
angular.module('app', modules);
那么你需要将$routeProvider
的类型从ng.IRouteProvider
改成ng.route.IRouteProvider
,因为那个定义是错误的。
// Url routing
angular.module('app').config(['$routeProvider',
function routes($routeProvider: ng.route.IRouteProvider) // *** $routeProvider is typed with ng.route.IRouteProvider ***
$routeProvider
.when('/',
templateUrl: 'views/MyView.html',
controller: 'app.controllers.MyController'
)
.otherwise(
redirectTo: '/'
);
]);
Next TypeScript 不接受空模块。所以拥有export module controllers
等是没有意义的,因为 TSC 不会包含它们,并且它们将是未定义的给出错误。除非您要在应用程序中定义至少一个控制器、指令、过滤器和服务。但这可以通过简单地包含 null;
module app
export module controllers null;
export module directives null;
export module filters null;
export module services null;
export interface IController
export interface IDirective
restrict: string;
link($scope: ng.IScope, element: JQuery, attrs: ng.IAttributes): any;
export interface IFilter
filter (input: any, ...args: any[]): any;
export interface IService
/**
* Register new controller.
*
* @param className
* @param services
*/
export function registerController (className: string, services = [])
var controller = 'app.controllers.' + className;
services.push(app.controllers[className]);
angular.module('app.controllers').controller(controller, services);
/**
* Register new filter.
*
* @param className
* @param services
*/
export function registerFilter (className: string, services = [])
var filter = className.toLowerCase();
services.push(() => (new app.filters[className]()).filter);
angular.module('app.filters').filter(filter, services);
/**
* Register new directive.
*
* @param className
* @param services
*/
export function registerDirective (className: string, services = [])
var directive = className[0].toLowerCase() + className.slice(1);
services.push(() => new app.directives[className]());
angular.module('app.directives').directive(directive, services);
/**
* Register new service.
*
* @param className
* @param services
*/
export function registerService (className: string, services = [])
var service = className[0].toLowerCase() + className.slice(1);
services.push(() => new app.services[className]());
angular.module('app.services').factory(service, services);
现在应该可以了,您可以注册控制器、过滤器、服务和指令。如:
module app.controllers
export class testCtrl implements IController
constructor()
console.log("Test Controller");
app.registerController('testCtrl');
当引用一个控制器,或服务时使用全名。即:
<div ng-controller="app.controllers.testCtrl"></div>
请记住在您的 html 中在 angular.js
之后引用 angular-route.js
。即:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular-route.js"></script>
【讨论】:
斯科特你的回答成功地解决了我的主要问题,所以再次非常感谢,但是我现在收到一个次要错误,说它无法加载模块 ngLocale。 (oi62.tinypic.com/ojkon.jpg) 在哪里(以及如何)在 app.ts 中加载这个模块?我在这里查看了文档:docs.angularjs.org/error/$injector/nomod,但我无法完全理解它。 @freschx 您可以在当前modules.push("ngRoute");
行之后使用modules.push("moduleName");
向模板添加更多模块。所以在这种情况下modules.push("ngLocale");
。希望有帮助:)
@Scott 有没有办法将module app.controllers
放入不同的文件中?我想将我的控制器打字稿文件拆分到不同的目录中。我试图将它拆分出来,但它没有注册任何控制器。【参考方案2】:
我在这里找到了我的解决方案a link:
当我试图包含一个不存在的模块依赖项时会发生这种情况。发生这种情况的原因有很多,例如删除模块的 index.html 脚本但留下模块依赖关系,甚至拼写错误的模块依赖关系。 (原来我的问题是前者。)所以一旦你知道这一点就很容易解决。
【讨论】:
以上是关于AngularJS Typescript 路由的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 TypeScript 解决 AngularJS 指令