ng-table v1.0.0: TypeError: Cannot read property 'page' of undefined
ng-table v1.0.0: TypeError: Cannot read property 'page' of undefined
我尝试使用示例中的 angularjs ng-table:
http://4dev.tech/2015/08/tutorial-basic-datatable-sorting-filtering-and-pagination-with-angularjs-and-ng-table/
angular.module('ngTableTutorial', ['ngTable'])
.controller('tableController', function ($scope, $filter, NgTableParams) {
$scope.users = [{"id":1,"first_name":"Philip","last_name":"Kim","email":"pkim0@mediafire.com","country":"Indonesia","ip_address":"29.107.35.8"},
{"id":2,"first_name":"Judith","last_name":"Austin","email":"jaustin1@mapquest.com","country":"China","ip_address":"173.65.94.30"},
{"id":3,"first_name":"Julie","last_name":"Wells","email":"jwells2@illinois.edu","country":"Finland","ip_address":"9.100.80.145"},
{"id":4,"first_name":"Gloria","last_name":"Greene","email":"ggreene3@blogs.com","country":"Indonesia","ip_address":"69.115.85.157"},
{"id":50,"first_name":"Andrea","last_name":"Greene","email":"agreene4@fda.gov","country":"Russia","ip_address":"128.72.13.52"}];
$scope.usersTable = new NgTableParams({
page: 1,
count: 10
}, {
total: $scope.users.length,
getData: function ($defer, params) {
$scope.data = $scope.users.slice((params.page() - 1) * params.count(), params.page() * params.count());
$defer.resolve($scope.data);
}
});
});
<!DOCTYPE html>
<html ng-app="ngTableTutorial">
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script>
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" media="screen">
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js" type="text/javascript"></script>
<link rel="stylesheet" href="https://rawgit.com/esvit/ng-table/master/dist/ng-table.min.css">
<script src="https://rawgit.com/esvit/ng-table/master/dist/ng-table.min.js"></script>
<!-- <link href="app/resources/css/style.css" rel="stylesheet" type="text/css"/>
<script src="app/resources/js/app.js" type="text/javascript"></script>-->
</head>
<body>
<div ng-controller="tableController">
<table ng-table="usersTable" class="table table-striped">
<tr ng-repeat="user in data">
<td data-title="'Id'" >
{{user.id}}
</td>
<td data-title="'First Name'" >
{{user.first_name}}
</td>
<td data-title="'Last Name'" >
{{user.last_name}}
</td>
<td data-title="'e-mail'" >
{{user.email}}
</td>
<td data-title="'Country'">
{{user.country}}
</td>
<td data-title="'IP'" >
{{user.ip_address}}
</td>
</tr>
</table>
</div>
</body>
</html>
并得到异常:
类型错误:无法读取未定义的 属性 'page'
我认为,这是因为 ng-table 转到了新版本 1.0.0。现在,这个例子不起作用了。
而且我想不通如何重写示例,以便它与新版本 ng-table 一起工作?
请帮助我。
UPD:或者您可以 post 独立示例,使用 ng-table 1.0.0、getdata、分页和过滤吗?
UPD:如果从 getData 参数中删除 $defer 则没有帮助。
它没有抛出异常,但不显示数据。
片段显示问题:
UPD 2016.08.16 1:15
我加行
$scope.data = $scope.users.slice((params.page() - 1) * params.count(), params.page() * params.count()) ;
现在显示数据,但不过滤。
如何重写代码段以过滤数据?
UPD 2016.08.16 1:36:
添加字符串
counts: [2, 4, 6, 10, 20],
和
<tr ng-repeat="user in $data track by user.id">
现在分页和过滤好了
angular.module('ngTableTutorial', ['ngTable'])
.controller('tableController', function($scope, $filter, NgTableParams) {
$scope.users = [
{ "id": 1, "first_name": "Philip", "last_name": "Kim", "email": "pkim0@mediafire.com", "country": "Indonesia", "ip_address": "29.107.35.8" },
{ "id": 2, "first_name": "Judith", "last_name": "Austin", "email": "jaustin1@mapquest.com", "country": "China", "ip_address": "173.65.94.30" },
{ "id": 3, "first_name": "Julie", "last_name": "Wells", "email": "jwells2@illinois.edu", "country": "Finland", "ip_address": "9.100.80.145" },
{ "id": 4, "first_name": "Gloria", "last_name": "Greene", "email": "ggreene3@blogs.com", "country": "Indonesia", "ip_address": "69.115.85.157" },
{ "id": 50, "first_name": "Andrea", "last_name": "Greene", "email": "agreene4@fda.gov", "country": "Russia", "ip_address": "128.72.13.52" }
];
$scope.usersTable = new NgTableParams({
page: 1,
count: 2
}, {
total: $scope.users.length,
counts: [2, 4, 6, 10, 20],
getData: function( params) {
params.total($scope.users.length);
$scope.data = $scope.users.slice((params.page() - 1) * params.count(), params.page() * params.count());
return $scope.data;
}
});
})
<html ng-app="ngTableTutorial">
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script>
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" media="screen">
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js" type="text/javascript"></script>
<link rel="stylesheet" href="https://rawgit.com/esvit/ng-table/master/dist/ng-table.min.css">
<script src="https://rawgit.com/esvit/ng-table/master/dist/ng-table.min.js"></script>
</head>
<body>
<div ng-controller="tableController">
<table ng-table="usersTable" class="table table-striped">
<tr ng-repeat="user in $data track by user.id">
<td data-title="'Id'" >
{{user.id}}
</td>
<td data-title="'First Name'" >
{{user.first_name}}
</td>
<td data-title="'Last Name'" >
{{user.last_name}}
</td>
<td data-title="'e-mail'" >
{{user.email}}
</td>
<td data-title="'Country'">
{{user.country}}
</td>
<td data-title="'IP'" >
{{user.ip_address}}
</td>
</tr>
</table>
</div>
</body>
</html>
从 0.8.x 到 1.0.0 版本有一些重大变化,记录在 github 存储库的 CHANGELOG
文件中:https://github.com/esvit/ng-table/blob/master/CHANGELOG.md#breaking-changes
正如@just.ru 已经指出的那样,您的问题可能是由 getData
签名的更改引起的。在早期版本中,第一个参数是 $defer
,$q
服务中已知的一些 deferred
对象。这允许进行异步调用并发出新数据已到达的信号。在 1.0.0 中,API 发生了变化,您现在可以直接 return 数据或 return 对您的数据的承诺。然后 ng-table 会为你处理一切。
因此,如果您的数据已经可用并且您不想使用服务器端过滤和排序,您可以像这样使用新的 dataset
属性:
$scope.users = [ /* your data... */ ];
假设。
$scope.usersTable = new NgTableParams({
// your config
}, {
dataset: $scope.users;
}
);
或者您可以通过相应地实施 getData
方法自行处理过滤:
$scope.usersTable = new NgTableParams({
// your config
}, {
getData: function(params) {
params.total($scope.users.length);
return $scope.users.slice((params.page() - 1) * params.count(), params.page() * params.count());
}
}
);
如果你的服务器支持过滤和分页,那么你必须根据响应设置一些属性。响应必须包含有关查询匹配的元素总数的信息。
假设您的 JSON 回复如下所示:
{
totalAmountOfMatchingItems: 33,
itemsOfTheCurrentPage: [
{ /*... */ }
]
}
您可能需要相应地实施您的 getData
:
$scope.usersTable = new NgTableParams({
// your config
}, {
getData: function(params) {
return $scope.backendApi.queryForResult(params).then(function(data) {
params.total(data.totalAmountOfMatchingItems);
return data.itemsOfTheCurrentPage;
});
}
}
);
调用 params.total()
方法很重要,以便 ng-table 知道它必须如何呈现分页。
更新:当您使用 getData
版本时,您还需要确保在迭代时为过滤的项目引用正确的值。之前,您将筛选的项目分配给 $scope.data
。这现在也由 ng-table 处理,它使用 $data
属性。因此,要修复您的代码段,您还需要相应地调整 ng-repeat
:
<tr ng-repeat="user in $data track by user.id">
我尝试使用示例中的 angularjs ng-table: http://4dev.tech/2015/08/tutorial-basic-datatable-sorting-filtering-and-pagination-with-angularjs-and-ng-table/
angular.module('ngTableTutorial', ['ngTable'])
.controller('tableController', function ($scope, $filter, NgTableParams) {
$scope.users = [{"id":1,"first_name":"Philip","last_name":"Kim","email":"pkim0@mediafire.com","country":"Indonesia","ip_address":"29.107.35.8"},
{"id":2,"first_name":"Judith","last_name":"Austin","email":"jaustin1@mapquest.com","country":"China","ip_address":"173.65.94.30"},
{"id":3,"first_name":"Julie","last_name":"Wells","email":"jwells2@illinois.edu","country":"Finland","ip_address":"9.100.80.145"},
{"id":4,"first_name":"Gloria","last_name":"Greene","email":"ggreene3@blogs.com","country":"Indonesia","ip_address":"69.115.85.157"},
{"id":50,"first_name":"Andrea","last_name":"Greene","email":"agreene4@fda.gov","country":"Russia","ip_address":"128.72.13.52"}];
$scope.usersTable = new NgTableParams({
page: 1,
count: 10
}, {
total: $scope.users.length,
getData: function ($defer, params) {
$scope.data = $scope.users.slice((params.page() - 1) * params.count(), params.page() * params.count());
$defer.resolve($scope.data);
}
});
});
<!DOCTYPE html>
<html ng-app="ngTableTutorial">
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script>
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" media="screen">
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js" type="text/javascript"></script>
<link rel="stylesheet" href="https://rawgit.com/esvit/ng-table/master/dist/ng-table.min.css">
<script src="https://rawgit.com/esvit/ng-table/master/dist/ng-table.min.js"></script>
<!-- <link href="app/resources/css/style.css" rel="stylesheet" type="text/css"/>
<script src="app/resources/js/app.js" type="text/javascript"></script>-->
</head>
<body>
<div ng-controller="tableController">
<table ng-table="usersTable" class="table table-striped">
<tr ng-repeat="user in data">
<td data-title="'Id'" >
{{user.id}}
</td>
<td data-title="'First Name'" >
{{user.first_name}}
</td>
<td data-title="'Last Name'" >
{{user.last_name}}
</td>
<td data-title="'e-mail'" >
{{user.email}}
</td>
<td data-title="'Country'">
{{user.country}}
</td>
<td data-title="'IP'" >
{{user.ip_address}}
</td>
</tr>
</table>
</div>
</body>
</html>
并得到异常: 类型错误:无法读取未定义的 属性 'page'
我认为,这是因为 ng-table 转到了新版本 1.0.0。现在,这个例子不起作用了。 而且我想不通如何重写示例,以便它与新版本 ng-table 一起工作?
请帮助我。
UPD:或者您可以 post 独立示例,使用 ng-table 1.0.0、getdata、分页和过滤吗?
UPD:如果从 getData 参数中删除 $defer 则没有帮助。 它没有抛出异常,但不显示数据。 片段显示问题:
UPD 2016.08.16 1:15 我加行 $scope.data = $scope.users.slice((params.page() - 1) * params.count(), params.page() * params.count()) ;
现在显示数据,但不过滤。 如何重写代码段以过滤数据?
UPD 2016.08.16 1:36: 添加字符串
counts: [2, 4, 6, 10, 20],
和
<tr ng-repeat="user in $data track by user.id">
现在分页和过滤好了
angular.module('ngTableTutorial', ['ngTable'])
.controller('tableController', function($scope, $filter, NgTableParams) {
$scope.users = [
{ "id": 1, "first_name": "Philip", "last_name": "Kim", "email": "pkim0@mediafire.com", "country": "Indonesia", "ip_address": "29.107.35.8" },
{ "id": 2, "first_name": "Judith", "last_name": "Austin", "email": "jaustin1@mapquest.com", "country": "China", "ip_address": "173.65.94.30" },
{ "id": 3, "first_name": "Julie", "last_name": "Wells", "email": "jwells2@illinois.edu", "country": "Finland", "ip_address": "9.100.80.145" },
{ "id": 4, "first_name": "Gloria", "last_name": "Greene", "email": "ggreene3@blogs.com", "country": "Indonesia", "ip_address": "69.115.85.157" },
{ "id": 50, "first_name": "Andrea", "last_name": "Greene", "email": "agreene4@fda.gov", "country": "Russia", "ip_address": "128.72.13.52" }
];
$scope.usersTable = new NgTableParams({
page: 1,
count: 2
}, {
total: $scope.users.length,
counts: [2, 4, 6, 10, 20],
getData: function( params) {
params.total($scope.users.length);
$scope.data = $scope.users.slice((params.page() - 1) * params.count(), params.page() * params.count());
return $scope.data;
}
});
})
<html ng-app="ngTableTutorial">
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script>
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" media="screen">
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js" type="text/javascript"></script>
<link rel="stylesheet" href="https://rawgit.com/esvit/ng-table/master/dist/ng-table.min.css">
<script src="https://rawgit.com/esvit/ng-table/master/dist/ng-table.min.js"></script>
</head>
<body>
<div ng-controller="tableController">
<table ng-table="usersTable" class="table table-striped">
<tr ng-repeat="user in $data track by user.id">
<td data-title="'Id'" >
{{user.id}}
</td>
<td data-title="'First Name'" >
{{user.first_name}}
</td>
<td data-title="'Last Name'" >
{{user.last_name}}
</td>
<td data-title="'e-mail'" >
{{user.email}}
</td>
<td data-title="'Country'">
{{user.country}}
</td>
<td data-title="'IP'" >
{{user.ip_address}}
</td>
</tr>
</table>
</div>
</body>
</html>
从 0.8.x 到 1.0.0 版本有一些重大变化,记录在 github 存储库的 CHANGELOG
文件中:https://github.com/esvit/ng-table/blob/master/CHANGELOG.md#breaking-changes
正如@just.ru 已经指出的那样,您的问题可能是由 getData
签名的更改引起的。在早期版本中,第一个参数是 $defer
,$q
服务中已知的一些 deferred
对象。这允许进行异步调用并发出新数据已到达的信号。在 1.0.0 中,API 发生了变化,您现在可以直接 return 数据或 return 对您的数据的承诺。然后 ng-table 会为你处理一切。
因此,如果您的数据已经可用并且您不想使用服务器端过滤和排序,您可以像这样使用新的 dataset
属性:
$scope.users = [ /* your data... */ ];
假设。
$scope.usersTable = new NgTableParams({
// your config
}, {
dataset: $scope.users;
}
);
或者您可以通过相应地实施 getData
方法自行处理过滤:
$scope.usersTable = new NgTableParams({
// your config
}, {
getData: function(params) {
params.total($scope.users.length);
return $scope.users.slice((params.page() - 1) * params.count(), params.page() * params.count());
}
}
);
如果你的服务器支持过滤和分页,那么你必须根据响应设置一些属性。响应必须包含有关查询匹配的元素总数的信息。
假设您的 JSON 回复如下所示:
{
totalAmountOfMatchingItems: 33,
itemsOfTheCurrentPage: [
{ /*... */ }
]
}
您可能需要相应地实施您的 getData
:
$scope.usersTable = new NgTableParams({
// your config
}, {
getData: function(params) {
return $scope.backendApi.queryForResult(params).then(function(data) {
params.total(data.totalAmountOfMatchingItems);
return data.itemsOfTheCurrentPage;
});
}
}
);
调用 params.total()
方法很重要,以便 ng-table 知道它必须如何呈现分页。
更新:当您使用 getData
版本时,您还需要确保在迭代时为过滤的项目引用正确的值。之前,您将筛选的项目分配给 $scope.data
。这现在也由 ng-table 处理,它使用 $data
属性。因此,要修复您的代码段,您还需要相应地调整 ng-repeat
:
<tr ng-repeat="user in $data track by user.id">