&



26 maart 2013

Iwan van Staveren

Agenda


  • Wie ben ik
  • Wat is Symfony
  • Wat is AngularJS
  • Waarom handig?
  • Hoe beide te gebruiken
  • Twig
  • FosRestBundle
  • Vragen


Wie ben ik?


Iwan van Staveren

Software architect bij Oracle
13 jaar ervaring met PHP
7 jaar ervaring met Symfony

nl.linkedin.com/in/iwanvanstaveren
Twitter: @istaveren

Wat is ?


Dat weten we hier wel :-)

Volgens symfony.com

Symfony is a PHP Web Development Framework. 
That doesn’t answer your question? 
Ok, let’s try that again. 
Symfony is a PHP Framework, a Philosophy, and a Community - all working together in harmony.

Wat is AngularJS

Een open-source Javascript framework

Of zo als ze het zelf zeggen:

HTML enhanced for web apps!




MVC

Models / Views / Controllers

Resources



        var User = $resource('/api/users/', {id: '@objectId'});

                        

// Default methods
{ 
    'get':    {method:'GET'},
    'save':   {method:'POST'},
    'query':  {method:'GET', isArray:true},
    'remove': {method:'DELETE'},
    'delete': {method:'DELETE'} 
};

... en nog veel meer!

Resources



...
User.prototype.isHacker = function() { return this.is_hacker; }
User.prototype.hackStuff = function(p) { this.current = p; }
...

                        

HTML


<div ng-controller="ItemsController">
    <p>Total items: <input ng-model="items" type="number" /></p>
    <ul>
        <li>Total items {{ items }} </li>
        <li>Total added {{ addTwo(items) }} </li>
    </ul>
<div>

Templates in HTML, niet in Javascript!

Controllers


function ItemController($scope)
{
  $scope.items = 2;

  $scope.addTwo = function(input) {
    return input + 2;
  }
}
                    

Demo

Items

  • Total items <[ items ]>
  • Items added <[ addTwo(items) ]>

Hoe te beginnnen



    <html ng-app="HackerApp">
        ...
        <div ng-controller="AwesomeHackerCtrl">...</div>
        <div ng-controller="SuperHackerCtrl">...</div>
    </html>


                        

Angular heeft zijn eigen scope in javascript en de DOM

ng-app



var DemoAppModule = angular.module('DemoApp', ['models']).
                config(function($interpolateProvider) {
        $interpolateProvider.startSymbol('<[');
        $interpolateProvider.endSymbol('>');
    });

                        

Config & setup

ng-controller



    // DemoData controller
    function DemoDataCtrl($window, $rootScope, $scope, $http, User) {

        $scope.users = User.query(function(data) {
            // Validate each User
        });

        $scope.validateUser = function(h) {
            // Determine if valid user
        };
    }

                        

Scoped local methods

Services



    angular.module('models', ['ngResource', 'ngCookies']).
    factory('Hacker', function($resource) {

        var Hacker = $resource("/api/hacker/:id", {id: "@id"})

        // Add class methods
        Hacker.login = function(data, success, error) {
            $http.post('/api/login/', data).
                success(success).
                error(error);
        });

                        

Directives

Pas de HTML aan zo als jij dat wilt. Mis je een <tab> tag in HTML dan kan je hem hiermee maken.

Eigenlijk een MVC in een tag.

Testen

Dat zit er bij net als bij Symfony.

Heet Karma en werkt als unit testen.


Starting Testacular Server (http://vojtajina.github.com/testacular)
-------------------------------------------------------------------
info: Testacular server started at http://localhost:9876/
info (launcher): Starting browser Chrome
info (Chrome 25.0): Connected on socket id TszbEIbJKa9gxm647LC3
Chrome 25.0: Executed 10 of 10 SUCCESS (0.435 secs / 0.1 secs)

Routing

ng-view



    <html ng-app="HackerApp">
        ...
        <div ng-view></div>
    </html>

                        

The Router



// Configure routes
HA.config(function($routeProvider, $locationProvider) {
    $routeProvider.
        when('/s/', {controller: SHCtrl, templateUrl: '/static/sh.html'}).
        when('/a/', {controller: AHCtrl, templateUrl: '/static/ah.html'}).
        otherwise({redirectTo: '/'});

    // Set HTML5 Mode for routes
    $locationProvider.html5Mode(true);
});

                        

Gotchas

(Or: things you wish they told you)

$resource

Distributed separately

$cookies

Also distributed separately

Therefore



<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
<script src="http://code.angularjs.org/angular-resource-1.0.5.min.js"></script>
<script src="http://code.angularjs.org/1.0.5/angular-cookies-1.0.5.min.js"></script>

                        

AngularJS is friendly

But it chooses its friends carefully

Waarom handig?

  • Meer logica naar de client
  • Geeft een betere response naar de gebruiker
  • Minder load op de server
  • Er komen steeds meer apps
  • Apps en web pagina's kunnen de zelfde backend API gebruiken

Vraag hoevel % code PHP / Javascript

In 2010?

In 2013?

In 2015?

Hoe beide te gebruiken?

Voeg AngulerJS toe aan je twig template

{% block foot_script %}
  {% if app.debug %}
    <script type="text/javascript" src="{{ asset('bundles/demo/js/angular/angular.js') }}"></script>
    <script type="text/javascript" src="{{ asset('bundles/demo/js/angular/angular-resource.js') }}"></script>
    <script type="text/javascript" src="{{ asset('bundles/demo/js/angular/angular-ui.js') }}"></script>
  {% else %}
    {%- javascripts
      '@DemoBundle/Resources/public/js/angular/angular.min.js'
      '@DemoBundle/Resources/public/js/angular/angular-resource.min.js'
      '@DemoBundle/Resources/public/js/angular/angular-ui.min.js'
    %}
      <script type="text/javascript" src="{{ asset_url }}"></script>
    {% endjavascripts %}
  {% endif %}
<script type="text/javascript" src="{{ asset('bundles/fosjsrouting/js/router.js') }}"></script>
<script type="text/javascript" src="{{ path('fos_js_routing_js', {"callback": "fos.Router.setData"}) }}"></script>
{% endblock %}

Let op! In dev mode gebruik niet de minified versie. Dat debugt niet echt handig in Javascript

Twig & AngularJS templates

Aangezien zowel AngularJS als Twig {{ }} gebruikt voor variable.

Moet er één worden aangepast.

Handigst is AngularJS op de volgende manier:


var DemoAppModule = angular.module('DemoApp', ['models']).
                config(function($interpolateProvider) {
        $interpolateProvider.startSymbol('<[');
        $interpolateProvider.endSymbol('>');
    });
                        

FOSRestBundle

Met de hulp van deze bundle krijg je data die normaal naar twig gaat eenvoudig terug als json response


    public function booksAction($name)
    {
      $view = View::create(array('books' => array("Book $name 1", "Book $name 2"), 'name' => $name));
      
      $view->setTemplate('AcmeDemoBundle:Demo:hello.html.twig');
      $handler = $this->get('fos_rest.view_handler');
      
      return $handler->handle($view);
    }

Geeft voor app_dev.php/demo/books/Iwan?_format=json


{"books":["Book Iwan 1","Book Iwan 2"],"name":"Iwan"}

Vragen

Credits for the slides: Vojta Jína, Miško Hevery, Igor Minar, Patrick Aljord.