【问题标题】:AngularJS - How to modularize a directive + template combination?AngularJS - 如何模块化指令+模板组合?
【发布时间】:2014-06-04 19:01:21
【问题描述】:

情况是这样的。我有一个指令,它依赖于一个 templateUrl。

指令看起来像这样:

angular.module('foo')
.directive('bar', function(){
  return {
    restrict: 'E',
    replace: true,
    templateUrl: '/foo/bar.html',
    controller: 'fooController',
    require: '^ngModel',
    scope: {
      onSuccess: '&'
    }
  };
});

此指令是我的一个应用程序的一部分,重要的是它始终是应用程序的一部分。但是,我也想在其他项目中使用相同的指令,目前我正在使用 bower 将存储库下拉到我的其他项目中。但是,该指令将中断,因为 templateUrl 不正确。 Bower 克隆了我的整个项目,模板的实际路径充其量在我的其他项目中需要是这样的:

/lib/public/foo/bar.html

其他人如何管理这个?

【问题讨论】:

    标签: angularjs bower directive


    【解决方案1】:

    由于可维护性问题,我从不喜欢使用模板字符串进行模板化。我的 html 原型制作速度非常快,所以我选择了一个繁重的任务,它读取我的文件并将它们处理成单个 $templateCache js 文件。

    解决方案

    Grunt Angular Templates

    Grunt 构建任务以连接和注册您的 AngularJS 模板 $templateCache

    // within my Gruntfile.js
    grunt.initConfig({
      ngtemplates: {
        'angular-my-directives': {
          src:      'views/**/*.html', // where my view files are
          dest:     'src/templates.js' // single file of $templateCache
        }
      }
      // ...
    });
    

    生成类似:./src/templates.js,它保留了我的文件夹结构:

    angular.module('angular-my-directives').run(['$templateCache', function($templateCache) {
    
      $templateCache.put('views/directives/my-download.html',
        "<form name=\"myDownloadForm\" ng-submit=\"submit()\" novalidate>\n" +
        "</form>"
      );
    
    }]);
    

    现在在我的指令中,我可以简单地使用 templateUrl: 'views/directives/my-download.html',它将使用 $templateCache。

    最后我使用grunt-contrib-concat 来合并我的文件以便于加载。

    查看“Grunt concat + uglify with sourcemaps”(或在 cmets 中留下更好的链接)以了解如何将 js 文件合并 + uglify(又名 min)到单个“dist”文件中。

    如果使用您自己的自定义凉亭包..

    确保将连接的(也称为构建的)文件提交到包 repo,以便您的包使用者可以简单地包含 my-concat-package.jsmy-concat-package.min.js

    【讨论】:

    • 这肯定会奏效,尽管它引入了一些开销,因为任何包含此指令的项目也需要包含此 grunt 脚本。每当模板发生变化时(例如,通过使用替换函数),使用 grunt 任务生成模板字符串可能更有意义
    • @bioball 确实发生了。在 grunt-concat 的最后一步,我在发布包时提交构建文件。 Grunt 只需要贡献/开发包 - 不是使用
    • 啊,明白了。是的,有道理。我原以为您将 $templateCache 逻辑放在包含该指令的应用程序中,但我现在明白了。我喜欢。对我来说似乎是最好的解决方案。
    • 在这种情况下,没有办法添加 css 文件......有什么最佳实践吗?我想在 HTML 模板中添加一个
    • @GiovanniBitliner,我将每种类型的资产编译成一个文件。所有 js 成单个 js 文件,所有 sass 编译成单个 css 文件。我永远不会自己插入/直接插入样式或其他资产(如字体)。我的目标是提供非常简单的 api,用于直接包含到页面(用户空间为每种文件类型安装 1 个文件很好),或捆绑在更大的应用程序中(供专业使用)。
    【解决方案2】:

    Angular 指令具有templateUrltemplate 属性。 template 接收一个 HTML 字符串。这不是一个完美的解决方案,因为您需要将 HTML 放入您的 JS 中。但是对于库创建者来说,将 HTML 字符串直接放在 template 属性上是一种常见的模式,这样他们就可以将他们的模块包装到一个文件中。

    您可能希望将 templateUrl-to-template 作为您的 lib 的构建步骤。

    看看Angular Bootstrap Bower Repo

    【讨论】:

    • 我考虑过使用template并将我的模板字符串化,但我还没有找到一个可以将jade模板转换为HTML、转换为javascript字符串并替换一行的构建过程在我的javascript文件中将其放置在那里。存在吗?
    • 我查看了 angular bootstrap bower repo,他们对 html 字符串进行了硬编码,我试图避免这样做
    • 它们可能不是真正的“硬编码”,它们可能使用类似 Grunt 插件的东西来生成这些东西:npmjs.org/package/grunt-angular-templates 我想我可能也必须这样做。 ..
    【解决方案3】:

    对此的一种解决方案,也是我个人首选的解决方案,是将模板放入$templateCacheModule.run 函数中。这样你就不用担心 url 引用了错误的东西——你可以给它任何你想要的任意识别 url——而且它永远不需要 http 请求来获取该模板并启动。

    【讨论】:

      【解决方案4】:

      在你的指令项目中:

      使用 xyz.tpl.html 文件名创建所有模板,并将所有 js 代码放入 your-directive 目录。所有 templateUrl 看起来像

      templateUrl: '/template/my.tpl.html'

      在应用项目中:

      在您的项目中创建一个 gulp/grunt 任务,用于将所有 *.tpl.html 文件从 bower_components 复制到 /template/ 目录中(默认)。

      例如:

      // copy template files
      gulp.task('copy-tpl', function() {
          return gulp.src([
              config.dirs.src.bower_components + '/**/*.tpl.html'
          ])
                  .pipe(flatten())
                  .pipe(gulp.dest(config.dirs.build.tpl));
      });
      

      重要! /template 目录是一个约定(如 js、css 等)。

      【讨论】:

      • 不得不将指令特定的 html 编译放在父应用程序中对我来说似乎不是很模块化
      【解决方案5】:

      您可以通过 gulp 使用 gulp-angular-templatecache 来执行此操作。

      你的指令看起来像这样:

      angular.module('foo').directive('bar', function($templateCache){
        return {
          restrict: 'E',
          replace: true,
          template: '$templateCache.get('bar.html')',
          controller: 'fooController',
          require: '^ngModel',
          scope: {
            onSuccess: '&'
          }
        };
      });
      

      你的gulpfile.js 看起来像这样:

      var gulp = require('gulp'),
          addTemplates = require('gulp-angular-templatecache');
      
      gulp.task('default', function() {
          gulp.src('templatesDir/**/*.html')
              .pipe(addTemplates('templateFile.js', {module: 'foo' }))
              .pipe(gulp.dest('dist'));
      });
      

      这会在您的 dist 文件夹中生成文件“templateFile.js”,然后可以将其与您的 bower.json 中的指令文件打包。

      【讨论】:

        【解决方案6】:

        我已经给了an answer 使用 grunt 将你的 html 文件构建到 $templateCache 文件中,但我已经切换到 gulp,所以任何想要遵循相同过程但使用 gulp 的人,结帐 gulp-angular-templatecache

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多