(function () { 'use strict'; BaseListController.$inject = ['$location', '$scope', '$controller', '$q', 'debounce', 'query']; /** * @name BaseListController * @extends AbstractDirectiveController * @constructor */ function BaseListController($location, $scope, $controller, $q, debounce, query) { angular.extend(this, $controller('AbstractDirectiveController', {$scope: $scope})); this.listReloatCounter = 0; this.options = { paginationInLocation: true, filterInLocation: true }; this.getLocationOptionsFromData = function (data) { var empty = true, result = {}; if (null == data) return result; if (this.options.filterInLocation && data.filter) { empty = false; result.filter = angular.copy(data.filter); } if (this.options.paginationInLocation && data.pagination) { empty = false; if (+data.pagination.currentPageIndex) { result.pagination = {page: +data.pagination.currentPageIndex || 0}; } } result = empty || !result ? undefined : query.encode(result); return result || {}; }; this.getListOptionsFromLocation = function (options) { options = angular.extend({filter: true, pagination: true}, options); options.filter = options.filter && this.options.filterInLocation; options.pagination = options.pagination && this.options.paginationInLocation; var search, result = {}; try { search = _.reduce($location.search(), function (search, value, key) { return (search ? search + '&' : '') + key + '=' + value; }, ''); result = query.decode(search); } catch (e) { result = {}; $location.search({}); } options.filter || delete result.filter; options.pagination || delete result.pagination; return search ? result : undefined; }; this.getListOptions = function (options) { options = angular.extend({filter: true, pagination: true}, options); var result = this.getListOptionsFromLocation(options); if (options.filter && $scope.filter) { result = result || {}; result.filter = angular.copy($scope.filter); } if (options.pagination && $scope.data && $scope.data.pagination) { result = result || {}; result.pagination = {page: $scope.data.pagination.currentPageIndex || 0}; } return result; }; /** * @param {Object} [options] Options for method BaseListController.getListOptions() * @return {promise} */ this.list = function (options) { return this.bridgeAction('list', this.getListOptions(options)).then( angular.bind(this, this.onListDone), angular.bind(this, this.onListFail) ); }; this.listAction = function (action) { return this.bridgeAction.apply(this, arguments).then( angular.bind(this, this.onListActionDone), angular.bind(this, this.onListActionFail) ); }; this.onListDone = function (response) { if ($scope.filter && response.data && response.data.filter && !angular.equals($scope.filter, response.data.filter)) { if (++this.listReloatCounter < 5) { return this.list(); } } this.listReloatCounter = 0; $scope.filterBusy = false; if (response && response.message) this.notify(response.message); $scope.data = response.data; $scope.filter = $scope.data && $scope.data.filter || {}; this.listUpdateLocation(response.data); return response; }; this.onListFail = function (response) { $scope.filterBusy = false; if (response && response.message) this.notify(response.message, 'warning'); $scope.data = {}; return $q.reject(response); }; this.onListActionDone = function (response) { if (response && response.message) this.notify(response.message); this.list(); return response; }; this.onListActionFail = function (response) { if (response && response.message) this.notify(response.message, 'warning'); this.list(); return $q.reject(response); }; this.listUpdateLocation = function (data) { var options; if ((options = this.getLocationOptionsFromData(data))) { $location.search(options); } }; this.filterReset = function () { $scope.filter = {}; return this.filterApply(); }; this.filterApply = function () { $scope.filterBusy = true; return this.list({pagination: false}); }; this.paginationChange = function () { this.list(); }; $scope.filterBusy = false; $scope.data = null; $scope.filter = null; $scope.filterData = null; $scope.filterReset = angular.bind(this, this.filterReset); $scope.filterApply = angular.bind(this, this.filterApply); $scope.filterApplyAuto = debounce($scope.filterApply, 750); $scope.paginationChange = angular.bind(this, this.paginationChange); } angular.module('app.service').controller('BaseListController', BaseListController); })();