加载相对的templateUrl

我一直在试图find创build模块化,可扩展的angular度应用程序的最佳方式。 我真的很喜欢angular-boilerplate , angular-app这样的项目结构,其中所有相关的文件都通过partials和directives的特性组合在一起。

project |-- partial | |-- partial.js | |-- partial.html | |-- partial.css | |-- partial.spec.js 

但是,在所有这些示例中,模板URL都是相对于基本url加载的,而不是相对于当前文件:

 angular.module('account', []) .config(function($stateProvider) { $stateProvider.state('account', { url: '/account', templateUrl: 'main/account/account.tpl.html', // this is not very modular controller: 'AccountCtrl', }); }) 

这不是非常模块化的,在大型项目中可能难以维护。 我需要记住每次移动这些模块时都要更改templateUrlpath。 这将是很好,如果有一种方法来加载相对于当前文件的模板,如:

 templateUrl: './account.tpl.html' 

有没有办法做这样的angular?

我想最终你会发现,如果可能的话,维护js文件的path将会更困难。 当需要发货的时候,你很可能会想把所有的javascript文件连接到一个文件,在这种情况下,你会希望模板是相对于baseUrl的。 另外,如果你通过ajax获取模板,除非你预先将它们打包在$ templateCache中,否则默认情况下,Angular会默认它们相对于baseUrl,所以服务器知道在哪里find它们文件已经被发送到浏览器。

也许你不喜欢让他们与开发中的baseUrl相关的原因是因为你没有在本地运行服务器? 如果是这样的话,我会改变这种情况。 这会让你的生活更加轻松,特别是如果你要使用路线。 我会检查出Grunt ,它有一个非常简单的服务器,你可以在本地运行来模仿一个名为Grunt Connect的生产设置。 你也可以签出像Yeoman这样的项目,它使用Grunt提供了一个预先打包的前端开发环境,所以你不必花费大量的时间进行设置。 Angular Seed项目也是本地开发Grunt设置的一个很好的例子。

现在最好的方法是使用像browserify,webpack或typescript这样的模块加载器。 还有很多其他的。 由于可以从文件的相对位置创build需求,并且可以通过转换或加载器(如partial)导入模板,所以您甚至不必再使用模板url。 只需简单地通过需求内联模板。

我的旧回答仍然可用如下:

我在这个主题上写了一篇文章,并在我们当地的Angular Meetup上发言。 我们大多数人现在正在生产中使用它。

只要你的文件结构在你的模块中有效地performance出来,这是相当简单的。 这里是解决scheme的快速预览。 全文链接如下。

 var module = angular.module('myApp.things', []); var all = angular.module('myApp.things.all', [ 'myApp.things', 'things.someThing', 'things.someOtherThing', 'things.someOtherOtherThing', ]); module.paths = { root: '/path/to/this/thing/', partials: '/path/to/this/thing/partials/', sub: '/path/to/this/thing/sub/', }; module.constant('THINGS_ROOT', module.paths.root); module.constant('THINGS_PARTIALS', module.paths.partials); module.constant('THINGS_SUB', module.paths.sub); module.config(function(stateHelperProvider, THINGS_PARTIALS) { stateHelperProvider.setNestedState({ name: 'things', url: '/things', templateUrl: THINGS_PARTIALS + 'things.html', }); }); 

然后任何子模块或“相对”模块如下所示:

 var module = angular.module('things.someThing', ['myApp.things']); var parent = angular.module('myApp.things'); module.paths = { root: parent.paths.sub + '/someThing/', sub: parent.paths.sub + '/someThing/sub/', partials: parent.paths.sub + '/someThing/module/partials/', }; module.constant('SOMETHING_ROOT', module.paths.root); module.constant('SOMETHING_PARTIALS', module.paths.partials); module.constant('SOMETHING_SUB', module.paths.sub); module.config(function(stateHelperProvider, SOMETHING_PARTIALS) { stateHelperProvider.setNestedState({ name: 'things.someThing', url: "/someThing", templateUrl: SOMETHING_PARTIALS + 'someThing.html', }); }); 

希望这可以帮助!

全文: 相对AngularJS模块

干杯!

我一直在咀嚼这个问题一段时间了。 我使用gulp来封装我的模板进行生产,但是我正在努力寻找一个我对开发满意的解决scheme。

这是我结束了。 下面的代码片段允许任何url被重新连线,只要你认为合适。

 angular.module('rm').config(function($httpProvider) { //this map can be defined however you like //one option is to loop through script tags and create it automatically var templateMap = { "relative.tpl.html":"/full/path/to/relative.tpl.html", etc... }; //register an http interceptor to transform your template urls $httpProvider.interceptors.push(function () { return { 'request': function (config) { var url = config.url; config.url = templateMap[url] || url; return config; } }; }); }); 

当然,有可能做你想用systemJs模块加载器。

 import usersTemplate from './users.tpl'; var directive = { templateUrl: usersTemplate.name } 

你可以在这里查看很好的例子https://github.com/swimlane-contrib/angular1-systemjs-seed

我一直在使用templateUrl: './templateFile.tpl.html但更新的东西,它打破了。 所以我把它扔在那里。

我一直在我的Gruntfile.js html2js对象中使用这个:

 html2js: { /** * These are the templates from `src/app`. */ app: { options: { base: '<%= conf.app %>', rename: function( templateName ) { return templateName.substr( templateName.lastIndexOf('/') ); } }, src: [ '<%= conf.app %>/**/{,*/}<%= conf.templatePattern %>' ], dest: '.tmp/templates/templates-app.js' } } 

我知道这可能会导致冲突,但对我来说,这是一个小问题,而不是每次编辑/path/to/modules/widgets/wigdetName/widgetTemplate.tpl.html文件时,我都会将其包含在另一个项目中。