How do I use separate templates with my angular directive bower package?

你离开我真会死。 提交于 2019-12-04 07:56:47

I've been on the hunt for guidance/advice on this very problem, and have considered a number of different options. I thought I'd share what I've settled on currently.

N.B. the project that this is approach is being used on is still in its early stages, so the approach described is by no means set in stone. I wouldn't be surprised if I had to adapt/change it in the future.

Background context is the same, we've got multiple self-contained directives living on GitHub that are used via bower. Each components template has to be inline with the directive, as templateUrl paths won't work.

I'm essentially doing option 2 from above, using gulp, and leveraging the angular template cache using the gulp-angular-templatecache plugin.

Solution

gulpfile.js

Does 2 things, parse component name and write template contents to template cache (via gulp plugin) and concatenate component code and mark-up into single file (into dist/<component-name>.js.

var gulp = require('gulp'),
    templates = require('gulp-angular-templatecache'),
    concat = require('gulp-concat'),
    clean = require('gulp-clean'),
    pkg = require('./package.json');

var template = 'myTemplate.tpl.html'

gulp.task('templates', function () {
  return gulp.src(template)
    .pipe(templates('templates.tmp', {
      root: '/templates/',
      module: pkg.name
    }))
    .pipe(gulp.dest('.'));
});

gulp.task('concat', ['templates'], function () {
  return gulp.src([pkg.main, 'templates.tmp'])
    .pipe(concat(pkg.name + '.js'))
    .pipe(gulp.dest('./dist/'));
});

gulp.task('clean', ['concat'], function () {
  gulp.src('./*.tmp', {read: false})
    .pipe(clean());
});

gulp.task('watch', function () {
  gulp.watch(['*.js', '*.html'], ['build']);
});

gulp.task('build', ['templates', 'concat', 'clean']);
gulp.task('default', ['build', 'watch']);

Output

The template gets set in the template cache, and the directive retrieves it via $templateCache.get(key) when setting the template attribute. This gives the single file output needed to use this component via bower, whilst allowing you to maintain the mark up in a separate file in source.

angular.module('myModule', []).directive('myDirective', function ($templateCache) {

  return {
    template: $templateCache.get('/template/myTemplate.tpl.html');
    link: function (scope, elm, attr) {

    }
  };
});

angular.module("myModule").run(["$templateCache", function($templateCache) {$templateCache.put("/template/myTemplate.tpl.html","<div>This is the template for your component</div>");}]);

Thoughts

  1. There's an additional overhead of having a build step when working on a component. Given the requirement, I don't think there's a way to completely avoid such a step. If it's not done during component build, then it'd have to be done at implementation time. Given those 2 options, I think it's better to do it in the component when the scope is narrow and clear.

  2. I'm not convinced my gulp tasks are entirely optimal. There's a certain amount of synchronicity, which runs contrary to "the gulp way". Could probably figure out how to improve it with some time/effort.

I used grunt-angular-templates "Grunt build task to concatenate & register your AngularJS templates in the $templateCache"

// within my Gruntfile.js
grunt.initConfig({
  ngtemplates: {
    'angular-my-directives': {
      src:      'views/**/*.html',
      dest:     'template.js'
    }
  }
  // ...
});

generates something like: ./template.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>"
  );

}]);

Now in my directive I can simply use templateUrl: 'views/directives/my-download.html' and it will use the $templateCache.

Finally I used grunt-contrib-concat to combine my files for easy loading.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!