Start a series of posts how to code apps. First ever app with AngularJS and Yii was very simple. We'll talk about a few topics. Demos find here Simple Single Page app with lots of data about Racing. I didnot write backend for it, because formatting JSON used in the app wasn't as simple.U can only browse list and details - without reloading the page ;) In AngularJS files u might find where the docs are downloaded. Folder with all oof the front (AngularJS files) looked like this (In images folder glyphicons.png files located):

Pix with folders

Let's start with a view in php:

<p>
example JSON doc {"MRData":{"xmlns":"http:\/\/ergast.com\/mrd\/1.2","series":"f1","url":"http://ergast.com/api/f1/2013/drivers/raikkonen/driverstandings.json","limit":"30","offset":"0","total":"1","StandingsTable":{"season":"2013","driverId":"raikkonen","StandingsLists":[{"season":"2013","round":"19","DriverStandings":[{"position":"5","positionText":"5","points":"183","wins":"1","Driver":{"driverId":"raikkonen","permanentNumber":"7","code":"RAI","url":"http:\/\/en.wikipedia.org\/wiki\/Kimi_R%C3%A4ikk%C3%B6nen","givenName":"Kimi","familyName":"Räikkönen","dateOfBirth":"1979-10-17","nationality":"Finnish"},              "Constructors":[{"constructorId":"lotus_f1","url":"http:\/\/en.wikipedia.org\/wiki\/Lotus_F1","name":"Lotus F1","nationality":"British"}]}]}]}}}<br/>
   </p>
<?php
//TEXT in origin todo._id & todo.text CHANGE to id &descr
$url = Yii::app()->request->baseUrl;
//<script src="'.$url.'/front/f1feeder/js/core.js">
//  <link rel="stylesheet" type="text/css" href="'.$url.'/front/f1feeder/css/app.css" />
echo '<div ng-app="F1FeederApp">
  <ng-view></ng-view>
 
  <script src="'.$url.'/front/f1feeder/js/app.js"></script>
  <script src="'.$url.'/front/f1feeder/js/services.js"></script>
  <script src="'.$url.'/front/f1feeder/js/controllers.js"></script>
</div>';

Next. let's discover html partials:

<!--drivers.html - list of drivers available -->
<input type="text" ng-model="nameFilter" placeholder="Search..."/>
<table>
<thead>
  <tr><th colspan="4">Drivers Championship Standings</th></tr>
</thead>
<tbody>
  <tr ng-repeat="driver in driversList | filter: searchFilter">
    <td>{{$index + 1}}</td>
    <td>
      <a href="#/drivers/{{driver.Driver.driverId}}">
        {{driver.Driver.givenName}}&nbsp;{{driver.Driver.familyName}}
      </a>
    </td>
    <td>{{driver.Constructors[0].name}}</td>
    <td>{{driver.points}}</td>
  </tr>
</tbody>
</table>
 
<!--driver.html - details about the driver -->

And, at last, the JS folder:

//app.js
angular.module('F1FeederApp', [
  'F1FeederApp.services',
  'F1FeederApp.controllers',
  'ngRoute'
]).
config(['$routeProvider', function($routeProvider) {
    var baseUrl = "http://localhost:8084/yiiangular/";
  $routeProvider.
    when("/drivers", {templateUrl: baseUrl + "front/f1feeder/partials/drivers.html", controller: "driversController"}).
    when("/drivers/:id", {templateUrl: baseUrl + "front/f1feeder/partials/driver.html", controller: "driverController"}).
    otherwise({redirectTo: '/drivers'});
}]);
 
//controllers.js
angular.module('F1FeederApp.controllers', []).
 
  /* Drivers controller */
  controller('driversController', function($scope, ergastAPIservice) {
    $scope.nameFilter = null;
    $scope.driversList = [];
    $scope.searchFilter = function (driver) {
        var re = new RegExp($scope.nameFilter, 'i');
        return !$scope.nameFilter || re.test(driver.Driver.givenName) || re.test(driver.Driver.familyName);
    };
 
    ergastAPIservice.getDrivers().success(function (response) {
        //Digging into the response to get the relevant data
        $scope.driversList = response.MRData.StandingsTable.StandingsLists[0].DriverStandings;
    });
  }).
 
  controller('driverController', function($scope, $routeParams, ergastAPIservice) {
    $scope.id = $routeParams.id;
    $scope.races = [];
    $scope.driver = null;
 
    ergastAPIservice.getDriverDetails($scope.id).success(function (response) {
        $scope.driver = response.MRData.StandingsTable.StandingsLists[0].DriverStandings[0]; 
    });
 
    ergastAPIservice.getDriverRaces($scope.id).success(function (response) {
        $scope.races = response.MRData.RaceTable.Races; 
    }); 
  });
 
//directives.js
'use strict';
angular.module('myApp.directives', []).
  directive('appVersion', ['version', function(version) {
    return function(scope, elm, attrs) {
      elm.text(version);
    };
  }]);
 
//filters.js
'use strict';
angular.module('myApp.filters', []).
  filter('interpolate', ['version', function(version) {
    return function(text) {
      return String(text).replace(/\%VERSION\%/mg, version);
    };
  }]);
 
//services.js
angular.module('F1FeederApp.services', [])
  .factory('ergastAPIservice', function($http) {
 
    var ergastAPI = {};
 
    ergastAPI.getDrivers = function() {
      return $http({
        method: 'JSONP', 
        url: 'http://ergast.com/api/f1/2013/driverStandings.json?callback=JSON_CALLBACK'
      });
    }
 
    ergastAPI.getDriverDetails = function(id) {
      return $http({
        method: 'JSONP', 
        url: 'http://ergast.com/api/f1/2013/drivers/'+ id +'/driverStandings.json?callback=JSON_CALLBACK'
      });
    }
 
    ergastAPI.getDriverRaces = function(id) {
      return $http({
        method: 'JSONP', 
        url: 'http://ergast.com/api/f1/2013/drivers/'+ id +'/results.json?callback=JSON_CALLBACK'
      });
    }
 
    return ergastAPI;
  });

Leave a Comment

Fields with * are required.

Please enter the letters as they are shown in the image above.
Letters are not case-sensitive.