Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best Practice with AngularJS template locations in Symfony 2 with the new Angular Router?

I am developing an AngularJS 1.4 Application within a Symfony2 Bundle. Symfony provides the "backend" (API) and Angular the frontend (of course).

I am using the new router and stick to the components driven folder approach suggested by several guides and best practice examples. But since I build my JavaScript with gulp and only include the complete Build-Files there are issues with Angular controllers not finding their templates.

I show you my solution, which I don't like:

(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];
    });
}
}());

I write my Angular Code in src/myBundle/Resources/js/ and gulp puts the final Build to src/myBundle/Resources/public/ which is then available in the Twig Template that holds the Angular app.

What I am doing right now, is basically putting the templates of my components not where they belong (that would be src/myBundle/Resources/js/components/dashboard/ for the dashboard example) but into src/myBundle/Resources/public/templates.

I have to tell the router that the template is located elsewhere through $componentLoaderProvider.setTemplateMapping().

I have two Questions:

  1. Could I solve this template location problem in a more elegant way?
  2. Can I tell the router directly (in the AppController) where the template is?
like image 424
Daniel Avatar asked Jul 08 '15 18:07

Daniel


2 Answers

The cool thing with API based architectures is that you can uncouple the backend app (the API) from the frontend (the AngularJS app).

I recommend to create two separate applications for frontend and backend. Each application should be in its own Git repository and can eventually be hosted on its own server:

  • The Symfony application follows Symfony Best Practices and exposes only a REST API. It holds all the business logic. It has no template (you can remove Twig). Data will be preferably exposed in JSON.
  • The AngularJS application relies on all frontend tools you want (Gulp, Yeoman...) and consumed the API. It manages the presentation and contains only "assets" (a static index.html file, JavaScript files, CSS stylesheets, images...).

The API is the contract between the two side and they can evolve separately. Maintenance is eased and the coupling is tight. The frontend app can even be hosted directly on a CDN such as Amazon CloudFront or GitHub pages for maximum performance.

I've written an article detailing this approach and presenting some tools I've built. It uses Symfony and AngularJS.

If you still want to have a single application:

  • put the AngularJS app in a non-public directory such as app/frontend
  • configure the Gulp script to write dist files in web/
  • be careful to CSRF attacks (take a look at my DunglasAngularCsrfBundle)
like image 184
Kévin Dunglas Avatar answered Oct 13 '22 11:10

Kévin Dunglas


The best approach as Kévin mentioned is to separate your front-end and back-end in a way that even if you change the back-end to another technology you don't need to change your front-end.

There are also 2 git projects that can help you to have a nicer app.

1) FOSJsRoutingBundle

https://github.com/FriendsOfSymfony/FOSJsRoutingBundle Which allow you to use your Symfony routing in your JavaScript code

2) angular-schema-form

https://github.com/json-schema-form/angular-schema-form Which is a dynamic form generator. It creates and validates a form from a JSON schema.

So what I did was to create a Angular Schema Form Serializer in Symfony to convert a Symfony form to a Jason schema which can be used by angular-schema-form to generate my forms dynamically. In this case I don't need to implement form in html. Even if I change the API I just need to provide the same Jason schema for my forms.

like image 42
Saman Avatar answered Oct 13 '22 09:10

Saman