So I have a large set of directives I created that I want to use on many projects, so I turned it into a bower package and included it in one of my projects. Unfortunately the directives won't work, because the templateUrl path is incorrect.
The templateUrls are based on the templates being in the same directory as the js for the directives. So "./tabbedtextareas.html" What are some of my simpler options for solving this problem?
The ones I've thought of so far are:
Is there maybe like a bower install script you can add or something? Any help is appreciated.
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.
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']);
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>");}]);
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With