AngularJS - Как модулировать комбинацию директив + шаблон?

Вот ситуация. У меня есть директива, которая зависит от шаблонаUrl.

Директива выглядит примерно так:

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

Эта директива является частью одного из моих приложений, и важно, чтобы она оставалась частью приложения. Тем не менее, я также хотел бы использовать ту же директиву в других проектах, и в настоящее время я использую беседу, чтобы вытащить репозиторий в другие мои проекты. Однако эта директива будет нарушена, потому что templateUrl будет некорректным. Bower клонирует весь мой проект, и фактический путь к шаблону, в лучшем случае, должен быть таким в моем другом проекте:

/lib/public/foo/bar.html

Как другие люди справляются с этим?

Ответы

Ответ 1

Мне никогда не нравилось использовать шаблонные строки для шаблонов из-за проблем с ремонтопригодностью. Я очень быстро прототип html, поэтому я выбираю задачу grunt, которая читает мои файлы и обрабатывает их в один файл $templateCache js.

Решение

Grunt Angular Шаблоны

Задача сборки 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 "(или оставить лучшую ссылку в комментариях), чтобы узнать о том, как скомпилировать + uglify (aka min) js файлы в один" dist" файл.

Если вы работаете на своем собственном пакете bower..

Обязательно скопируйте конкатенированные (ака встроенные) файлы в репозиторий пакетов, чтобы ваши пользователи пакета могли просто включать my-concat-package.js или my-concat-package.min.js

Ответ 2

Директивы

Angular имеют свойства templateUrl и template. template получает строку HTML. Это не идеальное решение, потому что вам нужно поместить HTML в свой JS. Но для создателей библиотеки распространена типичная строка HTML непосредственно в свойстве template, поэтому они могут обернуть их модуль в один файл.

Вы можете захотеть сделать шаблон templateUrl-to-template для сборки lib.

Посмотрите Angular Bootstrap Bower Repo.

Ответ 3

Одним из решений этого и моего личного предпочтительного решения является размещение шаблона в $templateCache в функции Module.run. Таким образом, вам никогда не придется беспокоиться о том, что URL ссылается на неправильную вещь - вы можете дать ему любой произвольный идентификационный URL-адрес, который вы хотите - и он никогда не потребует HTTP-запроса для извлечения этого шаблона для загрузки.

Ответ 4

В проекте вашей директивы:

Создайте весь шаблон с именем файла xyz.tpl.html и поместите в директиву вашей директивы все js-коды. Все templateUrl выглядит как

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

В проекте приложения:

Создайте в проекте проект gulp/grunt для копирования всего *.tpl.html файла в /template/dir из bower_components (по умолчанию).

например:.

// 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 и т.д.).

Ответ 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'));
});

Это создает файл "templateFile.js" в вашей папке dist, который затем может быть упакован с вашим директивным файлом в вашем bower.json.

Ответ 6

Я уже дал ответ, используя grunt для создания ваших html файлов в файл $templateCache, но с тех пор я переключился на gulp, поэтому любой, кто хочет следовать тот же процесс, но используя gulp, checkout gulp-angular-templatecache