Наилучшая практика использования шаблонов 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(),

У меня есть два вопроса:

  1. Могу ли я решить эту проблему с местоположением шаблона более элегантным способом?
  2. Могу ли я сказать маршрутизатору напрямую (в 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';
            }
Другие вопросы по тегам