Наилучшая практика использования шаблонов AngularJS в Symfony 2 с новым Angular Router?
Я занимаюсь разработкой приложения AngularJS 1.4 в составе пакета Symfony2. Symfony предоставляет "бэкэнд" (API) и Angular-интерфейс (конечно).
Я использую новый маршрутизатор и придерживаюсь подхода, управляемого папками для компонентов, предложенного в нескольких руководствах и примерах лучших практик Но так как я собираю свой JS с помощью gulp и включаю только полные файлы сборки, возникают проблемы с контроллерами Angular, которые не находят свои шаблоны.
Я покажу вам свое решение, которое мне не нравится:
(function () {
'use strict';
angular
.module('myModule', ['ngNewRouter', 'myModule.dashboard'])
.config(TemplateMapping)
.controller('AppController', AppController);
/* @ngInject */
function AppController ($router) {
$router.config([
{ path: '/', redirectTo: '/dashboard' },
{ path: '/dashboard', component: 'dashboard' }
]);
}
/* @ngInject */
function TemplateMapping($componentLoaderProvider) {
$componentLoaderProvider.setTemplateMapping(function (name) {
return {
'dashboard': '/bundles/mybundle/templates/dashboard/dashboard.html'
}[name];
});
}
}());
Я пишу свой угловой код в src/myBundle/Resources/js/
и глоток ставит финальную сборку в src/myBundle/Resources/public/
который затем доступен в шаблоне Twig, который содержит приложение Angular.
Сейчас я делаю шаблоны своих компонентов не там, где они находятся (это было бы src/myBundle/Resources/js/components/dashboard/
для примера приборной панели) но в src/myBundle/Resources/public/templates
,
Я должен сказать маршрутизатору, что шаблон находится в другом месте через $componentLoaderProvider.setTemplateMapping()
,
У меня есть два вопроса:
- Могу ли я решить эту проблему с местоположением шаблона более элегантным способом?
- Могу ли я сказать маршрутизатору напрямую (в
AppController
) где находится шаблон?
3 ответа
Отличительной особенностью архитектур на основе API является то, что вы можете отсоединить внутреннее приложение (API) от внешнего интерфейса (приложение AngularJS).
Я рекомендую создать два отдельных приложения для внешнего интерфейса и внутреннего интерфейса. Каждое приложение должно находиться в своем собственном Git-репозитории и в конечном итоге может быть размещено на его собственном сервере:
- Приложение Symfony следует рекомендациям Symfony и предоставляет только REST API. Он содержит всю бизнес-логику. У него нет шаблона (вы можете удалить Twig). Данные будут предпочтительно представлены в формате JSON.
- Приложение AngularJS опирается на все необходимые инструменты внешнего интерфейса (Gulp, Yeoman...) и использует API. Он управляет презентацией и содержит только "активы" (статический
index.html
файл, файлы JavaScript, таблицы стилей CSS, изображения...).
API - это контракт между двумя сторонами, и они могут развиваться отдельно. Техническое обслуживание облегчено, и муфта затянута. Приложение для внешнего интерфейса можно даже разместить непосредственно на CDN, например на страницах Amazon CloudFront или GitHub, для максимальной производительности.
Я написал статью, подробно описывающую этот подход и представляющую некоторые инструменты, которые я создал. Он использует Symfony и AngularJS.
Если вы все еще хотите иметь одно приложение:
- поместите приложение AngularJS в непубличный каталог, такой как
app/frontend
- настроить скрипт Gulp для записи файлов dist в
web/
- будьте осторожны с атаками CSRF (посмотрите на мой https://github.com/dunglas/DunglasAngularCsrfBundle)
Лучший подход, как упомянул Кевин, состоит в том, чтобы разделить ваш интерфейс и серверную часть таким образом, что даже если вы меняете серверную часть на другую технологию, вам не нужно менять интерфейс.
Есть также 2 git-проекта, которые могут помочь вам получить лучшее приложение.
1) FOSJsRoutingBundle
https://github.com/FriendsOfSymfony/FOSJsRoutingBundle которые позволяют использовать маршрутизацию Symfony в вашем коде JavaScript
2) угловая схема
https://github.com/json-schema-form/angular-schema-form Это генератор динамических форм. Он создает и проверяет форму из схемы JSON.
Поэтому я создал в Symfony сериализатор форм Angular Schema для преобразования формы Symfony в схему Jason, которая может использоваться angular-schema-form для динамического генерирования моих форм. В этом случае мне не нужно реализовывать форму в HTML. Даже если я изменю API, мне просто нужно предоставить ту же схему Jason для моих форм.
Лучший подход - полностью отделить ваше Angular-приложение от бэкэнда Symfony. Но если вы хотите использовать Angular в какой-то очень маленькой части своего унаследованного приложения, вы можете передать свой baseURL своему компоненту, например.:
<yourComponent baseurl="{{ app.request.scheme ~ '://' ~
app.request.httpHost ~ app.request.basePath }}"></yourComponent>
а затем использовать его в вашей функции templateUrl
templateUrl: function($attrs) {
return $attrs.baseurl + 'templats/yourComponent.template.html';
}