我是Angular.js和Smart Table的新手。我有一张桌子,按照我的意愿运作,除了一个我无法弄清楚的小问题。
我有一个selectDistinct下拉列表,用于过滤displayCollection,并且可以正常工作。
每行还有一个复选框,当您单击时,选择一行(或多行)。这也有效。
我遇到的问题是当我尝试两者同时进行时。如果我选择其中一个下拉过滤器,它会按预期过滤行。然后我点击其中一个复选框选择一行,一旦我这样做,表/过滤器重置,它再次显示我的所有记录。我希望select无需重置表格并保留我选择的过滤器即可运行。
以下是相关代码:
HTML
<table st-set-filter="customFilter" st-table="displayedCollection" st-safe-src="rowCollection">
<thead>
<tr class="table-header">
<th class="check"></th>
<th class="patient-name" st-sort="patientName">Patient Name</th>
<th class="patient-number" st-sort="patientNumber" st-skip-natural="true">Patient #</th>
<th class="prescription-type" st-sort="approvalType">Perscription Type</th>
<th class="date-of-birth" st-sort="dateRequested">Date Requested</th>
<th class="provider" st-sort="provider">Provider</th>
<th class="location" st-sort="location">Location</th>
<th class="status" st-sort="status">Status</th>
</tr>
<tr class="table-search">
<th class="check">
<st-select-all all="displayedCollection"></st-select-all>
</th>
<th class="patient-name">
<input class="patient-name" st-search="patientName" type="search" />
</th>
<th class="patient-number">
<input class="patient-number" st-search="patientNumber" type="search" />
</th>
<th class="prescription-type">
<st-select-distinct collection="rowCollection" predicate="approvalType"></st-select-distinct>
</th>
<th class="date-of-birth">
<input class="date-of-birth" st-search="dateRequested" type="search" />
</th>
<th class="provider">
<st-select-distinct collection="rowCollection" predicate="provider"></st-select-distinct>
</th>
<th class="location"></th>
<th class="status">
<st-select-distinct collection="rowCollection" predicate="status"></st-select-distinct>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in displayedCollection track by $index" index="{{$index}}" class="patient-profile" >
<td class="check" st-select="row">
<input type="checkbox" ng-checked="row.isSelected" id="checkbox{{$index}}">
<label class="checkbox-sm" for="checkbox{{$index}}"></label>
</td>
<td class="patient-name">{{row.patientName}}</td>
<td class="patient-number">{{row.patientNumber}}</td>
<td class="prescription-type">{{row.approvalType}}</td>
<td class="date-of-birth">{{row.dateRequested | date:'MM/dd/yyyy'}}</td>
<td class="provider">{{row.provider}}</td>
<td class="location">{{row.location}}</td>
<td class="status">{{row.status}}</td>
</tr>
</tbody>
JS
import angular from 'angular';
import ngRoute from 'angular-route';
import WidgetsController from './widgets.controller.js';
export default angular.module('pages.widgets', [ngRoute])
.config(config)
.controller('WidgetsController', WidgetsController)
.directive('stSelect', [stSelect])
.directive('stSelectAll', [stSelectAll])
.directive('stSelectDistinct', [stSelectDistinct])
.filter('customFilter', ['$filter', customFilter])
.name;
function config($routeProvider) {
$routeProvider.when('/widgets', {
template: require('./widgets.html'),
css: require('./widgets.scss'),
controller: 'WidgetsController'
});
}
config.$inject = ['$routeProvider'];
function stSelect() {
return {
require: '^stTable',
scope: {
row: '=stSelect'
},
link: function (scope, element, attr, ctrl) {
element.bind('change', function (evt) {
scope.$apply(function () {
ctrl.select(scope.row, 'multiple');
});
});
scope.$watch('row.isSelected', function (newValue, oldValue) {
if (newValue === true) {
element.parent().addClass('st-selected');
} else {
element.parent().removeClass('st-selected');
}
});
}
};
}
function stSelectAll() {
return {
restrict: 'E',
template: '<input type="checkbox" ng-model="isAllSelected" id="checkAll"><label class="checkbox-sm" for="checkAll"></label>',
scope: {
all: '='
},
link: function (scope, element, attr) {
scope.isAllSelected = false;
scope.$watch('isAllSelected', function () {
scope.all.forEach(function (val) {
val.isSelected = scope.isAllSelected;
});
});
}
};
}
function stSelectDistinct() {
return {
restrict: 'E',
require: '^stTable',
scope: {
collection: '=',
predicate: '@',
predicateExpression: '='
},
template: '<select ng-model="selectedOption" ng-change="optionChanged(selectedOption)" ng-options="opt for opt in distinctItems"></select>',
link: function (scope, element, attr, table) {
var getPredicate = function () {
var predicate = scope.predicate;
if (!predicate && scope.predicateExpression) {
predicate = scope.predicateExpression;
}
return predicate;
};
scope.$watch('collection', function (newValue) {
var predicate = getPredicate();
if (newValue) {
var temp = [];
scope.distinctItems = ['All'];
angular.forEach(scope.collection, function (item) {
var value = item[predicate];
if (value && value.trim().length > 0 && temp.indexOf(value) === -1) {
temp.push(value);
}
});
temp.sort();
scope.distinctItems = scope.distinctItems.concat(temp);
scope.selectedOption = scope.distinctItems[0];
scope.optionChanged(scope.selectedOption);
}
}, true);
scope.optionChanged = function (selectedOption) {
var predicate = getPredicate();
var query = {};
query.distinct = selectedOption;
if (query.distinct === 'All') {
query.distinct = '';
}
table.search(query, predicate);
};
}
};
}
function customFilter($filter) {
var filterFilter = $filter('filter');
var standardComparator = function standardComparator(obj, text) {
text = ('' + text).toLowerCase();
return ('' + obj).toLowerCase().indexOf(text) > -1;
};
return function customFilter(array, expression) {
function customComparator(actual, expected) {
var isBeforeActivated = expected.before;
var isAfterActivated = expected.after;
var isLower = expected.lower;
var isHigher = expected.higher;
var higherLimit;
var lowerLimit;
var itemDate;
var queryDate;
if (angular.isObject(expected)) {
//exact match
if (expected.distinct) {
if (!actual || actual.toLowerCase() !== expected.distinct.toLowerCase()) {
return false;
}
return true;
}
//matchAny
if (expected.matchAny) {
if (expected.matchAny.all) {
return true;
}
if (!actual) {
return false;
}
for (var i = 0; i < expected.matchAny.items.length; i++) {
if (actual.toLowerCase() === expected.matchAny.items[i].toLowerCase()) {
return true;
}
}
return false;
}
//date range
if (expected.before || expected.after) {
try {
if (isBeforeActivated) {
higherLimit = expected.before;
itemDate = new Date(actual);
queryDate = new Date(higherLimit);
if (itemDate > queryDate) {
return false;
}
}
if (isAfterActivated) {
lowerLimit = expected.after;
itemDate = new Date(actual);
queryDate = new Date(lowerLimit);
if (itemDate < queryDate) {
return false;
}
}
return true;
} catch (e) {
return false;
}
} else if (isLower || isHigher) {
//number range
if (isLower) {
higherLimit = expected.lower;
if (actual > higherLimit) {
return false;
}
}
if (isHigher) {
lowerLimit = expected.higher;
if (actual < lowerLimit) {
return false;
}
}
return true;
}
//etc
return true;
}
return standardComparator(actual, expected);
}
var output = filterFilter(array, expression, customComparator);
return output;
};
}