加载相对templateUrl

时间:2014-04-03 07:09:25

标签: angularjs angularjs-directive angular-ui-router angular-template

我一直在努力寻找创建模块化,可扩展角度应用程序的最佳方法。我非常喜欢angular-boilerplateangular-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'

有没有办法在角度做这样的事情?

5 个答案:

答案 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要小,我每次都将其包含在另一个项目中。