Подтвердить что ты не робот

Angular JS и Symfony2

В настоящее время я работаю над проектом с использованием Symfony2 и прошу совета по этому поводу.

Я думаю о гибридном приложении двумя (2) разными способами a). Страница входа должна использовать традиционную форму с токеном CRF и разрешать symfonty2 обрабатывать ее. b) Все внутренние страницы (которые потенциально являются модулями). Я хочу, чтобы они были не AJAX, но другие действия внутри должны вести себя как одиночная страница.

Например У меня есть модуль сотрудника. Когда пользователь нажимает на то, что он полностью загружен с сервера (все шаблоны и формы и т.д.), Теперь каждое действие под модулем сотрудника, например добавить/обновить удаление/просмотр и т.д., Должно быть загружено через AJAX и ответ будет возвращен в JSON, т.е. AngularJS.

В настоящее время я думаю об использовании FOSUserBundle, чтобы вернуть html на начальном запросе, а затем на основе типа запроса. Принять: application/json он вернет JSON (помните, как добавить/обновить часть удаления/просмотра?).

Мой вопрос - лучше ли использовать файлы Angular Partials (html) или Symfony2 Twig? или было бы лучше использовать Angular JS, но пусть эти частичные части будут отображаться веточкой Symfony2? (Я думаю о Формах здесь, хотел бы проверить это как со стороны клиента, так и с сервера)

Произошла ли какая-либо одна подобная проблема, если да, то какой подход был использован для разработки приложения HYBRID с использованием AngularJS и Symfony2 или любой другой структуры? любые соответствующие идеи приветствуются.

4b9b3361

Ответ 1

Я был в той же ситуации, что и вы. Проект AngularJS + Symfony2, API REST, вход в систему с использованием FOSUserBundle и т.д.

... И у всех есть плюсы и минусы, поэтому нет правильного пути, я просто скажу точно, что я сделал.

Я выбираю собственные шаблоны AngularJS, не проверяет CSRF, базовый шаблон, построенный с использованием Twig, проверку на стороне сервера, использование FOSJSRoutingBundle и некоторых помощников (BuiltResponse и BaseController).

Почему родные шаблоны?

С помощью дословно мы решаем переменные задачи, но у нас будет более сложная логика в наших шаблонах.

Мы также будем иметь менее масштабируемое приложение. Все шаблоны наших форм делают запрос в приложении Symfony, и один из лучших плюсов AngularJS загружает наши контроллеры, шаблоны и т.д. Из службы хранения данных, например S3 или CDN, например Cloudfront. Поскольку обработка на стороне сервера отсутствует, наши шаблоны будут загружаться намного быстрее. Очевидно, что даже с кешированием Twig медленнее.

И оба шаблона Twig и AngularJS действительно сложны в управлении, на собственном опыте. Я начал собирать их вместе, но было больно управлять.

Что я сделал?

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

И если вы создаете программное обеспечение как услугу, вам все равно придется это делать. Не будете ли вы загружать шаблоны форм из приложения в мобильное приложение, верно?

Почему нет проверки CSRF?

Мы не используем проверку CSRF в REST API, очевидно. Но, если вы хотите это сделать, вам нужно сделать запрос каждый раз, когда вы загружаете форму, чтобы получить токен CSRF. Это действительно, очень плохо. Итак, мы создаем CRUD, а также нам нужно создать "csrf-CRUD", еще 4 маршрута. Это не имеет никакого смысла.

Что я сделал?

Я отключил CSRF в формах.

Базовый шаблон?!

Угу. Базовый шаблон - это просто загрузка любого маршрута в нашем приложении. Вот что я делаю:

введите описание изображения здесь

Это поможет нам избежать ошибок, когда пользователи переходят непосредственно к URL-адресу приложения, если вы используете URL-адреса html5 angularjs. Просто так.

Проверка на стороне сервера, почему?

Если мы проверим валидацию в Angular, нам нужно сделать то же самое на стороне сервера, поэтому у нас есть 2 кода проверки для поддержки. Это болезненно. Каждое изменение, которое мы делаем в форме, нам нужно изменить валидацию в начале, проверку в обратном направлении, а также статическую форму Angular. Действительно, действительно больно.

Что я сделал?

В основном я сделал проверку на стороне сервера, используя ограничения Symfony. Для каждого запроса приложение проверяет форму и проверяет, была ли обнаружена какая-либо ошибка, если да, она получает первую и отправляет ее в качестве ответа.

В приложении AngularJS приложение проверяет, есть ли какая-либо ошибка внутри ключа ошибок. Таким образом, у нас есть процесс, используемый во всех приложениях для выполнения любого запроса формы. Это так:

введите описание изображения здесь

И маршруты?

Есть еще одна проблема: маршруты. Поместите URL прямо не надежным способом. Если мы изменим что-либо в URL-адресе, этот маршрут исчез, и пользователям это не понравится.

Чтобы исправить это, мы можем использовать FOSJsRoutingBundle. С помощью этой библиотеки мы можем поместить имя маршрута непосредственно в контроллер Angular, и он заполнит точный URL-адрес маршрута. Он полностью интегрирован с Symfony, поэтому параметры будут работать очень хорошо.

Вместо прямого использования url мы можем это сделать:

Routing.generate('panel_products_show', {id: $routeParams.product_id});

И вой! Мы получаем URL маршрута.


Это решит большую часть проблем, которые у вас есть. Но их больше.

Проблема 1 - Вводы форм

Формы из Symfony обычно имеют префикс, например "publish_product", поэтому каждое поле имеет имя типа [publish_product]name. Ах, как это было проблемой для меня.

В Angular публикация_продукт не считается массивом. Для этого нужно поставить одиночную кавычку, например ['publish_product']name. И это очень плохо, нам нужно изменить каждый ключ, чтобы использовать этот формат. В AngularJS я делал так:

{{ formData('[publish_product]name') }}

Абсолютно глупо.

Лучшим решением было просто удалить префикс формы в Symfony, используя метод createNamedBuilder вместо этого просто createBuilder. Я разрешаю первый параметр null, и да, нам больше не нужно использовать префикс. Теперь мы используем:

{{ formData.name }}

Намного лучше.

Проблема 2 - Маршруты жестко сохраняются

Каждый запрос может вернуть что-либо, мне нужно повторить много кода. Это очень сложно поддерживать, поэтому я просто создаю некоторые правила приложений, встроенные ответы, BaseController и т.д.

createNamedBuilder

createNamedBuilder - большой метод. Нам нужно сделать это для каждой формы:

введите описание изображения здесь

Это просто решить. Я просто создал BaseController, и я расширяю каждый контроллер от него. Я создал простой способ, который делает это.

введите описание изображения здесь

Для каждого маршрута нам не нужно повторять 3 строки, намного лучше.

Ответы

Когда мое приложение начало расти, у меня была серьезная проблема: все мои ответы разные. Это было очень трудно поддерживать. Для каждого запроса, который я делал, иногда я использовал "ответ", иногда "данные", сообщения об ошибках терялись в ответе и т.д.

Итак, я решил создать buildResponse, мне просто нужно установить некоторые параметры, и я получаю одинаковый результат для каждого маршрута, даже маршрутов GET.

введите описание изображения здесь

Клавиша

response показывает мне статус и сообщение. Это может быть ошибка или успех, а сообщение - необязательное поле, которое может быть пустым. Например, статус успеха с сообщением "Вы создали продукт".

data показывает мне любую информацию, которая мне нужна. Например, пользователь добавил продукт, и теперь ему нужна ссылка, чтобы увидеть его. В данных я помещаю url сообщения, и я легко могу получить его от контроллера AngularJS.

notifications - это особый ключ для моей бизнес-логики. Каждое действие может вернуть уведомление пользователю.

Неважно, какие ключи у вас есть. Самое главное - иметь стандартизованный ответ, потому что, когда ваше приложение будет расти, оно будет действительно полезно.

Это маршрут от моего контроллера:

введите описание изображения здесь

Полностью стандартизован. Инструмент качества кода Scrutinizer говорит, что все мои маршруты дублируются.: D

У вас есть BaseController и встроенный ответ. Когда я начал рефакторинг моего кода, каждый маршрут потерял около 4-10 строк.


Детали: getFormError возвращает первую ошибку формы. Вот мой метод:

public function getFormError(FormInterface $form)
{
    if ($form->getErrors()->current()) {
        return $form->getErrors()->current()->getMessage();
    }

    return 'errors.unknown';
}

... И параметры из buildResponse: 1. Статус. Я получаю его от константы в BaseController. Его можно изменить, поэтому я считаю важным не использовать строковое значение в каждом маршруте. 2. Сообщение о переводе. (Я использую preg_match, чтобы проверить, имеет ли он формат перевода, поскольку getFormError уже переводит ошибку). 3. Параметр data (array). 4. Параметр уведомлений (массив).

Другая проблема у меня будет

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

Я взял несколько месяцев, чтобы получить такой подход. Так много рефакторингов кода и вероятность гораздо больше в будущем. Поэтому я надеюсь, что это поможет кому-то не нужно делать то же самое.

1. Если я получу лучший способ сделать это, я обновлю этот ответ.

2. Я не умею писать английский, поэтому этот ответ, вероятно, будет иметь множество грамматических ошибок. Извините, я исправляю то, что вижу.