如何使搜索/分页在我的应用程序中可重用
how do I make searching/pagination reusable in my application?
我们决定在应用程序中使用服务器端分页。实现非常简单:
-
假设我们在服务器端有这样一个搜索操作:
[HttpGet] public ActionResult GetPeopleByName(String term, Int32 itemsPerPage = 10, Int32 page = 0) { var matches = this.people.Where(i => i.Name.Contains(term)); return Json( data: new { people = matches.Skip(itemsPerPage * page).Take(itemsPerPage).OrderBy(i => i.Name), total = matches.Count() }, behavior: JsonRequestBehavior.AllowGet ); }
-
在客户端上,我们有一个
subscriptionHolderController
:app.controller('subscriptionHolderController', ['$scope', '$http', function($scope, $http) { $scope.matches = []; $scope.itemsPerPage = 5; $scope.currentPage = 0; $scope.searchTerm = ''; // $scope.prevPage = function() { ... }; // $scope.prevPageDisabled = function() { ... }; // $scope.nextPage = function() { ... }; // $scope.nextPageDisabled = function() { ... }; $scope.pageCount = function() { return Math.ceil($scope.totalPages / $scope.itemsPerPage); }; $scope.$watch('currentPage', function() { $scope.search(); }); $scope.search = function() { if($scope.searchTerm === '') return; // initiate a GET-request with params: { page: $scope.currentPage, term: $scope.searchTerm, itemsPerPage: $scope.itemsPerPage } } $scope.matchesFound = function () { return $scope.matches.length > 0; } }]);
问题
结果我们得到了一个简单的CCD_ 2。但我们的应用程序需要另外一种具有一些附加功能的搜索类型,它不使用搜索词,其结果集应该以与上面所示相同的方式进行分页。
如何为不同类型的搜索重用分页逻辑?
在服务器端,您可以返回一个泛型类,该类将保存您的数据,即行的总数。
public class PagedResult<T>
{
public PagedResult(IEnumerable<T> data, long total)
{
Data = data;
Total = total;
}
public PagedResult()
{
}
public IEnumerable<T> Data { get; set; }
public long Total { get; set; }
}
你也可以为任何函数抽象输入参数,比如:
public class PageInfo
{
public int Page { get; set; }
public int PageSize { get; set; }
public int Skip
{
get
{
return PageSize*(Page - 1);
}
}
public PageInfo(int page, int pageSize)
{
Page = page;
PageSize = pageSize;
}
}
一个实际的例子可能是:
[HttpGet]
public ActionResult GetPeopleByName(String term, PageInfo pageinfo) {
var matches = this.people.Where(i => i.Name.Contains(term));
var pagedResult = new PagedResult<AnySearchType>{
data = matches.Skip(pageinfo.skip).Take(pageinfo.size).OrderBy(i => i.Name),
total = matches.Count()
};
return Json(
data: pagedResult,
behavior: JsonRequestBehavior.AllowGet
);
}
在客户端,您可以使用一个指令,通过传递以下参数来抽象分页的逻辑:
视图
<div class="box-content" scroll-pager="pagerConfig">
your data
<div>
控制器:
你可以通过一些配置,比如:
$scope.pagerConfig = {
pageSize: 10,
data: 'model.Data', // some text reference to your model
total: 'model.Total', // some text reference to your model
currentPage: 1,
searchParamName: 'Text',// some text reference to your model
resource: projectResource,// pass a resource object
success: function (data, page, total) {
}
};
为分页创建单独的类。在这个类中,您可以定义分页方法,您可以将分页应用于任何类型,并且使用不同的参数,您还可以自定义要应用分页的字段和页面大小。
这就是我最终得到的:
app.directive('pager', function() {
return {
restrict: 'EA',
scope: {
onChange: '&',
items: '=',
itemsPerPage: '@'
},
replace: true,
templateUrl: '/scripts/js/app/pager.html',
link: function(scope, el, attrs) {
scope.currentPage = 1;
scope.isFirstPage = function() {
return scope.currentPage === 1;
}
scope.decPage = function() {
if(scope.currentPage > 1) --scope.currentPage;
}
scope.isLastPage = function() {
return scope.currentPage >= scope.totalPages();
}
scope.totalPages = function() {
return Math.ceil(scope.items.total / scope.itemsPerPage);
}
scope.incPage = function() {
if(!scope.isLastPage()) ++scope.currentPage;
}
scope.$watch("currentPage", function(value) {
scope.onChange({page: value, itemsPerPage: scope.itemsPerPage});
});
}
};
});
标记
<div id="content" ng-app="subscriptionsManager">
<div ng-controller="subscriptionHolderController">
<div class="row">
<div class="columns medium-6 large-6">
<div class="searchbar">
<div class="searchbar-inner">
<input ng-model="searchTerm" type="text" />
<button ng-click="search(1, 35)" class="tiny">search</button>
</div>
</div>
<div pager items-per-page="35" items="data" on-change="respondToTheChange(page, itemsPerPage)"></div>
</div>
<div class="columns medium-6 large-6">
<div class="button-group filter-sample">
<button ng-click="toggleState1()" ng-class="{true: 'selected', false: 'secondary'}[state1]" class="tiny">filter1</button>
<button ng-click="toggleState2()" ng-class="{true: 'selected', false: 'secondary'}[state2]" class="tiny">filter2</button>
<button ng-click="toggleState3()" ng-class="{true: 'selected', false: 'secondary'}[state3]" class="tiny">filter3</button>
<button ng-click="search2(1, 35)" class="tiny">search</button>
</div>
<div pager items-per-page="35" items="data2" on-change="respondToTheChange2(page, itemsPerPage)"></div>
</div>
</div>
</div>
</div>
控制器
// search using a search term
$scope.data = { items: [], total: 0 };
$scope.searchTerm = '';
$scope.state1 = false;
$scope.state2 = false;
$scope.state3 = false;
$scope.toggleState1 = function() {
$scope.state1 = !$scope.state1;
}
$scope.toggleState2 = function() {
$scope.state2 = !$scope.state2;
}
$scope.toggleState3 = function() {
$scope.state3 = !$scope.state3;
}
$scope.search = function(page, itemsPerPage) {
if($scope.searchTerm === '') return;
if(!angular.isDefined(page) || page == null) page = 1;
if(!angular.isDefined(itemsPerPage) || itemsPerPage == null) itemsPerPage = 35;
$http({
url: '/subscriptions/GetSubscribersByNamePaged',
method: 'GET',
params: { term: $scope.searchTerm, page: page, itemsPerPage: itemsPerPage }
})
.success(function(data, status, headers, config) {
$scope.data = data;
}).error(function(data, status, headers, config) {
console.log('error: ' + data);
});
}
// search using anything else
$scope.search2 = function(page, itemsPerPage) {
if(!angular.isDefined(page) || page == null) page = 1;
if(!angular.isDefined(itemsPerPage) || itemsPerPage == null) itemsPerPage = 35;
$http({
url: '/subscriptions/GetSubscribersByFilters',
method: 'GET',
params: { state1: $scope.state1, state2: $scope.state2, state3: $scope.state3, page: page, itemsPerPage: itemsPerPage }
})
.success(function(data, status, headers, config) {
$scope.data2 = data;
}).error(function(data, status, headers, config) {
console.log('error: ' + data);
});
}
// bind searches!
$scope.respondToTheChange = function(page, itemsPerPage) {
$scope.search(page, itemsPerPage);
}
$scope.respondToTheChange2 = function(page, itemsPerPage) {
$scope.search2(page, itemsPerPage);
}
相关文章:
- 我在哪里从 React Redux 应用程序中的服务器获取初始数据
- 有没有一种方法可以在IE8中解决我的Rails javascript应用程序.js的问题
- 获取包含我的谷歌应用程序脚本的页面的url
- 胡子.js卡在我的 Rails 应用程序中的 0.4.0-dev 上
- 如何消除我的应用程序上的希腊字符
- 我的应用程序中的可点击元素应始终是锚标记
- 如何创建重用我的 JS 库的 iPad 应用程序,这些库是为 Web 应用程序构建的
- ASP.NET:是否可以将CSS或Javascript注入到我的Web应用程序中的每个页面中
- 为什么IE无法正确显示我的HttpHandler Web应用程序中的特殊符号
- 为什么我的应用程序中的某些组件在IE7中工作,而在IE9中不起作用
- 为什么我的Mac应用程序中的WebView html拒绝加载JQuery或任何外部脚本
- Angularjs模式窗口在我的应用程序中的实现
- 我曾经跟随某人的代码样本,并尝试应用到我的HighChart程序,但我可以'I don’我一点也做不到
- 如何从我的web应用程序中的Java脚本文件中获得加密的密码
- 如何始终解析相对于我的web应用程序根的URL
- 我可以使用标准Javascript应用程序中的Google Polymer吗
- Facebook应用程序-我如何计算发件人邀请的朋友数量
- 访问导致我的应用程序崩溃的数组元素
- 我的网络应用程序中的谷歌地图API
- Javascript应用程序-我的代码怎么样