我一直在努力寻找创建模块化,可扩展角度应用程序的最佳方法。我非常喜欢angular-boilerplate,angular-app等项目的结构,其中所有相关文件按部分和指令的特征组合在一起。
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',
});
})
这不是非常模块化的,并且可能难以在大型项目中维护。每次移动任何这些模块时,我都需要记住更改templateUrl
路径。如果有某种方法可以相对于当前文件加载模板,那就太好了:
templateUrl: './account.tpl.html'
有没有办法在角度做这样的事情?
答案 0 :(得分:16)
我认为你最终会发现,即使可能,维护相对于js文件的路径也会更难。当发货时,您很可能想要将所有javascript文件连接到一个文件,在这种情况下,您将希望模板相对于baseUrl。另外,如果你是通过ajax获取模板,默认情况下Angular会这样做,除非你在$ templateCache中预先打包它们,你肯定会想要它们相对于baseUrl,所以服务器知道你的js在哪里找到它们文件已经发送到浏览器。
也许你不喜欢在开发过程中使用它们相对于baseUrl的原因是因为你不是在本地运行服务器?如果是这样的话,我会改变这种情况。这将使您的生活更轻松,特别是如果您打算使用路线。我会查看Grunt,它有一个非常简单的服务器,您可以在本地运行以模仿名为Grunt Connect的生产设置。您还可以签出像Yeoman这样的项目,它使用Grunt提供预先打包的前端开发环境,因此您不必花费大量时间进行设置。 Angular Seed项目也是本地开发的Grunt设置的一个很好的例子。
答案 1 :(得分:15)
现在最好的方法是使用像browserify,webpack或typescript这样的模块加载器。还有很多其他的。由于需要可以从文件的相对位置,以及能够通过变换或加载器(如partialify)导入模板的额外奖励,您甚至不必再使用模板URL。只需通过require来内联模板即可。
我的旧回答仍然可以在下面找到:
我写了一篇关于这个主题的文章,并在我们当地的Angular Meetup上发表了演讲。我们大多数人现在都在生产中使用它。
只要您的模块中有效地表示您的文件结构,它就非常简单。以下是该解决方案的快速预览。完整的文章链接如下。
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',
});
});
然后是任何子模块或者#34;亲属"模块看起来像这样:
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',
});
});
希望这有帮助!
完整文章:Relative AngularJS Modules
干杯!
答案 2 :(得分:1)
我现在已经在这个问题上咀嚼了一段时间。我使用gulp打包我的模板进行生产,但我很难找到一个我很满意的开发解决方案。
这是我结束的地方。下面的代码段允许您根据需要重新连接任何网址。
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;
}
};
});
});
答案 3 :(得分:1)
Currenly可以使用systemJs模块加载器来做你想做的事。
import usersTemplate from './users.tpl';
var directive = {
templateUrl: usersTemplate.name
}
您可以在https://github.com/swimlane-contrib/angular1-systemjs-seed
查看好的示例答案 4 :(得分:-1)
我一直在使用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
要小,我每次都将其包含在另一个项目中。