var app = angular.module('app', ['ngTouch', 'ui.grid', 'ui.grid.pinning']);

app.controller('MainCtrl', ['$scope', '$http', '$log', '$interval', '$timeout', function ($scope, $http, $log, $interval, $timeout) {
  var start = new Date();
  var sec = $interval(function () {
    var wait = parseInt(((new Date()) - start) / 1000, 10);
    $scope.wait = wait + 's';
  }, 1000);
 
  // you could of course just include the template inline in your code, this example shows a template being returned from a function
  function rowTemplate() {
    return $timeout(function() {
      $scope.waiting = 'Done!';
      $interval.cancel(sec);
      $scope.wait = '';
      return '<div ng-class="{ \'my-css-class\': grid.appScope.rowFormatter( row ) }">' +
                 '  <div ng-if="row.entity.merge" style="overflow: hidden;" class="ui-grid-cell">{{row.entity.title}} - {{row.entity.name}}</div>' +
                 '  <div ng-if="!row.entity.merge" ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ng-class="{ \'ui-grid-row-header-cell\': col.isRowHeader }"  ui-grid-cell></div>' +
                 '</div>';
    }, 1100);
  }
 
  // Access outside scope functions from row template
  $scope.rowFormatter = function( row ) {
    return row.entity.gender === 'male'; 
  };
 
  $scope.waiting = 'Waiting for row template...';
  
  
  $scope.gridOptions = {
    rowTemplate: rowTemplate()
  };

  $scope.gridOptions.columnDefs = [
    { name:'id', width:50, enablePinning:false },
    { name:'name', width:100, pinnedLeft:true },
    { name:'age', width:100, pinnedRight:true  },
    { name:'address.street', width:150  },
    { name:'address.city', width:150 },
    { name:'address.state', width:50 },
    { name:'address.zip', width:50 },
    { name:'company', width:100 },
    { name:'email', width:100 },
    { name:'phone', width:200 },
    { name:'about', width:300 },
    { name:'friends[0].name', displayName:'1st friend', width:150 },
    { name:'friends[1].name', displayName:'2nd friend', width:150 },
    { name:'friends[2].name', displayName:'3rd friend', width:150 },
  ];

  $http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/500_complex.json')
    .success(function(data) {
      data[1].merge = true;
      data[1].title = "A merged row";
      $scope.gridOptions.data = data;
    });
}]);
.grid {
  width: 100%;
  height: 500px;
}
<!doctype html>
<html ng-app="app">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular-touch.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular-animate.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/csv.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/pdfmake.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/vfs_fonts.js"></script>
    <script src="http://ui-grid.info/release/ui-grid-unstable.js"></script>
    <link rel="stylesheet" href="http://ui-grid.info/release/ui-grid-unstable.css" type="text/css">
    <link rel="stylesheet" href="main.css" type="text/css">
  </head>
  <body>

<div ng-controller="MainCtrl">
  <div ui-grid="gridOptions" class="grid" ui-grid-pinning></div>
</div>


    <script src="app.js"></script>
  </body>
</html>