首页 文章

加载相对templateUrl

提问于
浏览
42

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

  • 16

    我想你最终会发现,即使可能,维护相对于js文件的路径也会更难 . 当发货时,您很可能想要将所有javascript文件连接到一个文件,在这种情况下,您将希望模板相对于baseUrl . 另外,如果你是通过ajax获取模板,默认情况下Angular会这样做,除非你在$ templateCache中预先打包它们,你肯定会想要它们相对于baseUrl,所以服务器知道你的js在哪里找到它们文件已经发送到浏览器 .

    也许是因为你没有在本地运行服务器?如果是这样的话,我会改变它 . 这将使您的生活更轻松,特别是如果您打算使用路线 . 我会查看Grunt,它有一个非常简单的服务器,你可以在本地运行来模仿一个名为Grunt Connect的 生产环境 设置 . 您还可以签出像Yeoman这样的项目,它使用Grunt提供预打包的前端开发环境,因此您不必花费大量时间进行设置 . Angular Seed项目也是本地开发的Grunt设置的一个很好的例子 .

  • 1

    现在最好的方法是使用像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',
        });
    });
    

    然后任何子模块或“相对”模块看起来像这样:

    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

    干杯!

  • 15

    我一直在咀嚼这个问题一段时间了 . 我使用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;
          }
        };
      });
    });
    
  • -1

    Currenly可以使用systemJs modules loader做你想做的事 .

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

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

  • 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 更小,每次都将它包含在另一个项目中 .

相关问题