UNPKG

11.1 kBJavaScriptView Raw
1/**
2 * ngTable: Table + Angular JS
3 *
4 * @author Vitalii Savchuk <esvit666@gmail.com>
5 * @url https://github.com/esvit/ng-table/
6 * @license New BSD License <http://creativecommons.org/licenses/BSD/>
7 */
8import * as ng1 from 'angular';
9import { NgTableParams } from '../core';
10/**
11 * The controller for the {@link ngTable ngTable} and {@link ngTableDynamic ngTableDynamic} directives
12 */
13export var NgTableController = (function () {
14 function NgTableController($scope, $timeout, $parse, $compile, $attrs, $element, $document, ngTableColumn, ngTableEventsChannel) {
15 this.$scope = $scope;
16 this.$parse = $parse;
17 this.$compile = $compile;
18 this.$attrs = $attrs;
19 this.$element = $element;
20 this.$document = $document;
21 this.ngTableColumn = ngTableColumn;
22 this.ngTableEventsChannel = ngTableEventsChannel;
23 var isFirstTimeLoad = true;
24 $scope.$filterRow = { disabled: false };
25 $scope.$loading = false;
26 // until such times as the directive uses an isolated scope, we need to ensure that the check for
27 // the params field only consults the "own properties" of the $scope. This is to avoid seeing the params
28 // field on a $scope higher up in the prototype chain
29 if (!$scope.hasOwnProperty("params")) {
30 $scope.params = new NgTableParams(true);
31 }
32 this.delayFilter = (function () {
33 var timer;
34 return function (callback, ms) {
35 $timeout.cancel(timer);
36 timer = $timeout(callback, ms);
37 };
38 })();
39 // watch for when a new NgTableParams is bound to the scope
40 // CRITICAL: the watch must be for reference and NOT value equality; this is because NgTableParams maintains
41 // the current data page as a field. Checking this for value equality would be terrible for performance
42 // and potentially cause an error if the items in that array has circular references
43 this.$scope.$watch('params', function (newParams, oldParams) {
44 if (newParams === oldParams || !newParams) {
45 return;
46 }
47 newParams.reload();
48 }, false);
49 this.subscribeToTableEvents();
50 }
51 Object.defineProperty(NgTableController.prototype, "hasVisibleFilterColumn", {
52 get: function () {
53 var _this = this;
54 if (!this.$scope.$columns)
55 return false;
56 return this.some(this.$scope.$columns, function ($column) {
57 return $column.show(_this.$scope) && !!$column.filter(_this.$scope);
58 });
59 },
60 enumerable: true,
61 configurable: true
62 });
63 NgTableController.prototype.onDataReloadStatusChange = function (newStatus /*, oldStatus*/) {
64 if (!newStatus || this.$scope.params.hasErrorState()) {
65 return;
66 }
67 var currentParams = this.$scope.params;
68 var filterOptions = currentParams.settings().filterOptions;
69 if (currentParams.hasFilterChanges()) {
70 var applyFilter = function () {
71 currentParams.page(1);
72 currentParams.reload();
73 };
74 if (filterOptions.filterDelay) {
75 this.delayFilter(applyFilter, filterOptions.filterDelay);
76 }
77 else {
78 applyFilter();
79 }
80 }
81 else {
82 currentParams.reload();
83 }
84 };
85 NgTableController.prototype.compileDirectiveTemplates = function () {
86 if (!this.$element.hasClass('ng-table')) {
87 this.$scope.templates = {
88 header: (this.$attrs.templateHeader ? this.$attrs.templateHeader : 'ng-table/header.html'),
89 pagination: (this.$attrs.templatePagination ? this.$attrs.templatePagination : 'ng-table/pager.html')
90 };
91 this.$element.addClass('ng-table');
92 var headerTemplate = null;
93 // $element.find('> thead').length === 0 doesn't work on jqlite
94 var theadFound_1 = false;
95 ng1.forEach(this.$element.children(), function (e) {
96 if (e.tagName === 'THEAD') {
97 theadFound_1 = true;
98 }
99 });
100 if (!theadFound_1) {
101 headerTemplate = ng1.element('<thead ng-include="templates.header"></thead>', this.$document);
102 this.$element.prepend(headerTemplate);
103 }
104 var paginationTemplate = ng1.element('<div ng-table-pagination="params" template-url="templates.pagination"></div>', this.$document);
105 this.$element.after(paginationTemplate);
106 if (headerTemplate) {
107 this.$compile(headerTemplate)(this.$scope);
108 }
109 this.$compile(paginationTemplate)(this.$scope);
110 }
111 };
112 NgTableController.prototype.loadFilterData = function ($columns) {
113 var _this = this;
114 ng1.forEach($columns, function ($column) {
115 var result = $column.filterData(_this.$scope);
116 if (!result) {
117 delete $column.filterData;
118 return undefined;
119 }
120 if (isPromiseLike(result)) {
121 delete $column.filterData;
122 return result.then(function (data) {
123 // our deferred can eventually return arrays, functions and objects
124 if (!ng1.isArray(data) && !ng1.isFunction(data) && !ng1.isObject(data)) {
125 // if none of the above was found - we just want an empty array
126 data = [];
127 }
128 $column.data = data;
129 });
130 }
131 else {
132 return $column.data = result;
133 }
134 });
135 function isPromiseLike(val) {
136 return val && typeof val === 'object' && typeof val.then === 'function';
137 }
138 };
139 NgTableController.prototype.buildColumns = function (columns) {
140 var _this = this;
141 // todo: use strictNullChecks and remove guard clause
142 var result = [];
143 (columns || []).forEach(function (col) {
144 result.push(_this.ngTableColumn.buildColumn(col, _this.$scope, result));
145 });
146 return result;
147 };
148 NgTableController.prototype.parseNgTableDynamicExpr = function (attr) {
149 if (!attr || attr.indexOf(" with ") > -1) {
150 var parts = attr.split(/\s+with\s+/);
151 return {
152 tableParams: parts[0],
153 columns: parts[1]
154 };
155 }
156 else {
157 throw new Error('Parse error (expected example: ng-table-dynamic=\'tableParams with cols\')');
158 }
159 };
160 NgTableController.prototype.setupBindingsToInternalScope = function (tableParamsExpr) {
161 // note: this we're setting up watches to simulate angular's isolated scope bindings
162 var _this = this;
163 // note: is REALLY important to watch for a change to the ngTableParams *reference* rather than
164 // $watch for value equivalence. This is because ngTableParams references the current page of data as
165 // a field and it's important not to watch this
166 this.$scope.$watch(tableParamsExpr, function (params) {
167 if (params === undefined) {
168 return;
169 }
170 _this.$scope.params = params;
171 }, false);
172 this.setupFilterRowBindingsToInternalScope();
173 this.setupGroupRowBindingsToInternalScope();
174 };
175 NgTableController.prototype.setupFilterRowBindingsToInternalScope = function () {
176 var _this = this;
177 if (this.$attrs.showFilter) {
178 this.$scope.$parent.$watch(this.$attrs.showFilter, function (value) {
179 _this.$scope.show_filter = value;
180 });
181 }
182 else {
183 this.$scope.$watch(function () { return _this.hasVisibleFilterColumn; }, function (value) {
184 _this.$scope.show_filter = value;
185 });
186 }
187 if (this.$attrs.disableFilter) {
188 this.$scope.$parent.$watch(this.$attrs.disableFilter, function (value) {
189 _this.$scope.$filterRow.disabled = value;
190 });
191 }
192 };
193 NgTableController.prototype.setupGroupRowBindingsToInternalScope = function () {
194 var _this = this;
195 this.$scope.$groupRow = { show: false };
196 if (this.$attrs.showGroup) {
197 var showGroupGetter_1 = this.$parse(this.$attrs.showGroup);
198 this.$scope.$parent.$watch(showGroupGetter_1, function (value) {
199 _this.$scope.$groupRow.show = value;
200 });
201 if (showGroupGetter_1.assign) {
202 // setup two-way databinding thus allowing ngTableGrowRow to assign to the showGroup expression
203 this.$scope.$watch('$groupRow.show', function (value) {
204 showGroupGetter_1.assign(_this.$scope.$parent, value);
205 });
206 }
207 }
208 else {
209 this.$scope.$watch('params.hasGroup()', function (newValue) {
210 _this.$scope.$groupRow.show = newValue;
211 });
212 }
213 };
214 NgTableController.prototype.getVisibleColumns = function () {
215 var _this = this;
216 return (this.$scope.$columns || []).filter(function (c) {
217 return c.show(_this.$scope);
218 });
219 };
220 NgTableController.prototype.subscribeToTableEvents = function () {
221 var _this = this;
222 this.$scope.$watch('params.isDataReloadRequired()', function (newStatus /*, oldStatus*/) {
223 _this.onDataReloadStatusChange(newStatus);
224 });
225 this.ngTableEventsChannel.onAfterReloadData(function (params, newDatapage) {
226 var visibleColumns = _this.getVisibleColumns();
227 if (params.hasGroup()) {
228 _this.$scope.$groups = (newDatapage || []);
229 _this.$scope.$groups.visibleColumnCount = visibleColumns.length;
230 }
231 else {
232 _this.$scope.$data = (newDatapage || []);
233 _this.$scope.$data.visibleColumnCount = visibleColumns.length;
234 }
235 }, this.$scope, function (publisher) { return _this.$scope.params === publisher; });
236 this.ngTableEventsChannel.onPagesChanged(function (params, newPages) {
237 _this.$scope.pages = newPages;
238 }, this.$scope, function (publisher) { return _this.$scope.params === publisher; });
239 };
240 NgTableController.prototype.some = function (array, predicate) {
241 var found = false;
242 for (var i = 0; i < array.length; i++) {
243 var obj = array[i];
244 if (predicate(obj)) {
245 found = true;
246 break;
247 }
248 }
249 return found;
250 };
251 NgTableController.$inject = [
252 '$scope', '$timeout', '$parse', '$compile', '$attrs', '$element', '$document', 'ngTableColumn', 'ngTableEventsChannel'
253 ];
254 return NgTableController;
255}());
256//# sourceMappingURL=ngTableController.js.map
\No newline at end of file