我正在尝试创建一个使用ng-grid与ASP.NET WebAPI的简单工作示例。因此,我从ng网格示例页面(
http://angular-ui.github.io/ng-grid/)中的服务器端分页示例开始;无论如何,我的网格总是显示空列,即使在调试时,我可以确认数据被正确接收。可能我只是在网格设置中遗漏了一些东西,但是我发现的所有样本看起来和我的相似。有人可以帮忙吗?这里是我做的:
更新#1:建议的解决方案似乎有效,但仅适用于第1页。每当我移动到新页面或进行任何其他需要刷新的操作时,即使服务器返回的数据按预期更改,显示的数据也保持不变。另外,从所有的代码示例中,我发现设置数据的正确方法似乎只是替换数组成员的值,而不是清空并重新填充它。我试过与https://groups.google.com/forum/#!searchin/angular/nggrid/angular/vUIfHWt4s_4/oU_C9w8j-uMJ提出的申请,但我得到相同的结果。
服务器端
只需创建一个新的MVC4应用程序,更新NuGet软件包,并添加角度和ng网格软件包。
我的假数据模型由Item类表示:
public sealed class Item { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public bool IsFemale { get; set; } }
我还添加了几个模型来处理分页,过滤和排序各种数据集(我发现更容易有一个常见的寻呼基础模型-PagedFilter-和一些派生模型):
public class PagedFilter { private int _nPageSize; private int _nPageNumber; public int PageSize { get { return _nPageSize; } set { if (value < 1) throw new ArgumentOutOfRangeException("value"); _nPageSize = value; } } public int PageNumber { get { return _nPageNumber; } set { if (value < 1) throw new ArgumentOutOfRangeException("value"); _nPageNumber = value; } } public int TotalItems { get; set; } public int TotalPages { get { return (int)Math.Ceiling((double)(TotalItems / PageSize)); } } public PagedFilter() { _nPageSize = 20; _nPageNumber = 1; } }
这是ItemFilter:
public class ItemFilter : PagedFilter { public List<string> SortFields { get; set; } public List<string> SortDirections { get; set; } public string Name { get; set; } public int? MinAge { get; set; } public int? MaxAge { get; set; } }
public class ItemController : ApiController { // fake data private readonly List<Item> _items; public ItemController() { Random rnd = new Random(); _items = new List<Item>(); char c = 'a'; for (int i = 0; i < 1000; i++) { _items.Add(new Item { Id = i,Age = rnd.Next(1,100),IsFemale = ((i & 1) == 0),Name = String.Format(CultureInfo.InvariantCulture,"{0:00000}-{1}",i,new string(c,5)) }); if (++c > 'z') c = 'a'; } } public dynamic Get([FromUri] ItemFilter filter) { var items = _items.AsQueryable(); // filtering if (!String.IsNullOrEmpty(filter.Name)) items = items.Where(i => i.Name.Contains(filter.Name)); if (filter.MinAge.HasValue) items = items.Where(i => i.Age >= filter.MinAge.Value); if (filter.MaxAge.HasValue) items = items.Where(i => i.Age <= filter.MaxAge.Value); // ...sorting (using Dynamic Linq) omitted for brevity... // paging int nTotalItems = items.Count(); items = items.Skip((filter.PageNumber - 1) * filter.PageSize) .Take(filter.PageSize); return new { totalItems = nTotalItems,items = items.ToArray() }; } }
客户端
在客户端,我的角度应用程序只是在ng网格样本上建立的单个控制器:因此,我直接添加属性到$ scope,即使在一个现实世界的情况下,我宁愿使用一个模型(可能从一个TypeScript类)。 HTML:
<div ng-app="MyApp" ng-controller="MainController"> <div ng-grid="gridOptions" style="height: 400px"> </div> </div>
JS:
var app = angular.module('MyApp',['ngGrid']); app.controller('MainController',['$scope','$http',function ($scope,$http,$apply) { $scope.items = []; // filter $scope.filterOptions = { filterText: "",useExternalFilter: true }; // paging $scope.totalServerItems = 0; $scope.pagingOptions = { pageSizes: [25,50,100],pageSize: 25,currentPage: 1 }; // sort $scope.sortOptions = { fields: ["name"],directions: ["ASC"] }; // grid $scope.gridOptions = { data: "items",columnDefs: [ { field: "name",displayName: "Name",pinnable: true },{ field: "age",displayName: "Age",width: "60" },{ field: "isFemale",displayName: "F",width: "40" } ],enablePaging: true,enablePinning: true,pagingOptions: $scope.pagingOptions,filterOptions: $scope.filterOptions,keepLastSelected: true,multiSelect: false,showColumnMenu: true,showFilter: true,showGroupPanel: true,showFooter: true,sortInfo: $scope.sortOptions,totalServerItems: "totalServerItems",useExternalSorting: true,i18n: "en" }; $scope.refresh = function() { setTimeout(function () { var p = { name: $scope.filterOptions.filterText,pageNumber: $scope.pagingOptions.currentPage,pageSize: $scope.pagingOptions.pageSize,sortFields: $scope.sortOptions.fields,sortDirections: $scope.sortOptions.directions }; $http({ url: "/api/item",method: "GET",params: p }).success(function(data,status,headers,config) { $scope.totalServerItems = data.totalItems; // SUGGESTION #1 -- empty and fill the array /* $scope.items.length = 0; angular.forEach(data.items,function (item) { $scope.items.push(item); }); */ // https://groups.google.com/forum/#!searchin/angular/nggrid/angular/vUIfHWt4s_4/oU_C9w8j-uMJ $scope.$apply(function () { $scope.items = data.items; }); if (!$scope.$$phase) { $scope.$apply(); } }).error(function(data,config) { alert(JSON.stringify(data)); }); },100); }; // watches $scope.$watch('pagingOptions',function (newVal,oldVal) { if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) { $scope.refresh(); } },true); $scope.$watch('filterOptions',oldVal) { if (newVal !== oldVal) { $scope.refresh(); } },true); $scope.$watch('sortOptions',true); $scope.refresh(); }]);
在我的代码中,成功回调被调用,我可以浏览data.items中的所有返回的项。然而,网格中没有显示任何内容。控制台中没有出现错误。
经过一番尝试,我觉得我找到了正确的代码。关于$ apply的这篇文章帮助了我一点:
http://jimhoskins.com/2012/12/17/angularjs-and-apply.html.事实上,如果我理解的很好,所以申请的呼吁根本不需要,因为我的数据来自已经提供的$ http。所以,我结束只是在成功回调中设置范围项变量。这是完整的JS再次,希望这可以帮助一些像我这样的新手。现在我将使用TypeScript模型,服务和所有真实世界的东西来扩展测试:我怕我必须做一些新的帖子… 原文链接:https://www.f2er.com/angularjs/144994.html