Edit in JSFiddle

var myApp = angular.module('myApp', ['ngTable', 'ODataResources']);

myApp.controller('MyCtrl', ['$scope', 'odataTableService',
  function($scope, odataTableService) {
    $scope.tableParams = odataTableService.createTableParams({
      endPoint: 'http://services.odata.org/V3/Northwind/Northwind.svc/Products'
    });
  }
]);

myApp.service('odataTableService', [
  'NgTableParams',
  '$odataresource',
  '$odata',
  function(NgTableParams, $odataresource, $odata) {

    this.createTableParams = function(definition) {

      if (definition.endPoint === "" || definition.endPoint == null)
        throw "You must specify an odata endpoint url";

      /* initial params */
      var params = {
        page: 1,
        count: 10
      };

      var settings = {
        getData: function(params) {
					
          var query = $odataresource(definition.endPoint, {}, {}, {
            odatakey: definition.entityKey || 'Id'/*,
            isodatav4: true*/
          }).odata();

          if (definition.expand != null) {
            query = query.expand(definition.expand);
          }

          if (definition.predicate != null) {
            query = query.filter(definition.predicate);
          }
          // build predicates from params
          if (params.hasFilter()) {
            var predicateArray = [];
            _(params.filter())
              .forOwn(function(prop, key) {
                if (prop != null && prop !== "") {
                  var expandedKey = key.replace(".", "/");
                  if (_(prop).isNumber()) {
                    predicateArray.push(new $odata.Predicate(expandedKey, '=', prop));
                  } else {
                    predicateArray.push(new $odata
                      .Predicate(new $odata.Func("startswith", expandedKey, prop), true));
                  }
                }
              });
            query = query.filter($odata.Predicate.and(predicateArray));
          }

          // build ordering
          if (params.orderBy().length > 0) {
            _(params.orderBy())
              .forEach(function(item) {
                var direction = item.substring(0, 1);
                var field = item.substring(1);
                if (direction === "+") {
                  query = query.orderBy(field, "asc");
                } else {
                  query = query.orderBy(field, "desc");
                }
              });
          }

          return query.skip((params.page() - 1) * params.count())
            .take(params.count())
            .withInlineCount()
            .query(function(resource, headers) {
                console.log("query done");
              },
              function(error) {
                console.log(error);
              })
            .$promise.then(function(data) {
              params.total(data["odata.count"]);
              return data;
            });
        }
      }

      return new NgTableParams(params, settings);
    }
  }
]);
<div ng-controller="MyCtrl">
  <table class="table table-striped table-condensed table-hover" ng-table="tableParams" data-show-filter="true">
            <colgroup>
                <col />
                <col />
                <col />
            </colgroup>
            <tr data-ng-repeat="x in $data">
                <td data-title="'Name'" data-sortable="'ProductName'" data-filter="{ 'ProductName': 'text' }">
                    <div>
                        {{x.ProductName}}
                    </div>
                </td>
                <td data-title="'Unit price'" data-sortable="'UnitPrice'" data-filter="{ 'UnitPrice': 'number' }">
                    <div>
                        {{x.UnitPrice}}
                    </div>
                </td>
                <td data-title="'In stock'" data-sortable="'UnitsInStock'" data-filter="{ 'UnitsInStock': 'number' }">
                    <div>
                        {{x.UnitsInStock}}
                    </div>
                </td>
            </tr>
        </table>
</div>