问题
i have page with ng-table which works fine with initial data. I have a select box which send server request based on the option selected and then Iam getting new data to angular but is not updated with ng-table.
Here is my view:
<section data-ng-controller="ReportsController">
<div class="plain-box">
<table ng-table="tableParams" show-filter="true" class="table table-striped">
<thead>
<tr>
<th ng-repeat="column in columns" ng-show="column.visible"
class="text-center sortable" ng-class="{
'sort-asc': tableParams.isSortBy(column.field, 'asc'),
'sort-desc': tableParams.isSortBy(column.field, 'desc')
}"
ng-click="tableParams.sorting(column.field, tableParams.isSortBy(column.field, 'asc') ? 'desc' : 'asc')">
{{column.title}}
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in $data">
<td ng-repeat="column in columns" sortable="column.field">
{{user[column.field]}}
</td>
</tr>
</tbody>
</table>
</div>
My controller:
angular.module('reports').controller('ReportsController', ['$scope', '$stateParams', '$location', 'Authentication', 'Reports', '$filter', 'ngTableParams',
function($scope, $stateParams, $location, Authentication, Reports, $filter, ngTableParams ) {
$scope.reportBillingPeriod = 0;
$scope.$watch('reportBillingPeriod', function(newValue, oldValue) {
$scope.findReportData( newValue );
});
//$scope.reportBillingData = 0;
$scope.findReportData = function( selectedMonth ){
var selectedPeriod = selectedMonth;
if( selectedPeriod === null )
selectedPeriod = '0';
$scope.customers_report = Reports.customer_report({
monthReport: selectedPeriod
}, function( result ){
var data = result.customers;
$scope.columns = [
{ title: 'Account Name', field: 'accountName', visible: true, filter: { 'name': 'text' } },
{ title: 'Gross Revenue', field: 'planTotalAmount', visible: true }
];
$scope.$watch('result', function () {
$scope.tableParams.settings().$scope = $scope;
$scope.tableParams.reload();
});
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
filter: {
name: 'O' // initial filter
}
}, {
total: data.length, // length of data
getData: function($defer, params) {
var orderedData = params.sorting() ? $filter('orderBy')(data, params.orderBy()) : data;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
//$scope.reportBillingData = new Date();
}
});
});
};
}]);
回答1:
$scope.$watch('result', function () {
$scope.tableParams.settings().$scope = $scope; <<--nested scope is replacing!!
$scope.tableParams.reload();
});
ngTable directive create nested scope which inculde all settings for directive to work,so you shoudn't replace it with scope of ReportsController
you need to remove this row
$scope.tableParams.settings().$scope = $scope;
And you need to specify all parameters for ngTable,please have a look
here In ngTables, running $scope.tableParams.reload() for the third time results in TypeError: Cannot set property '$data' of null
UPDATE
and also it's better take ngTableParams intialization and $watch for result outside findReportData function in order to prevent errors and unnecessary re-initialization
UPDATE 2
i set up plunk,try to make it more look like original question,and mock httpservice,
but that's not matter,all data access must be going inside getData
func in ngTableParams
and when set up all filter you need to call(or maybe just using $watch
like in plunk) you have to call $scope.tableParams.reload();
,you can try to type some numbers in input above and data will be updating without problem.all code related to sorting ,pagging and filtering is removed for clarity,
so getData
look like following:
getData: function($defer, params) {
var selectedPeriod = $scope.reportBillingPeriod ; //selectedMonth;
if( selectedPeriod === null )
selectedPeriod = '0';
$scope.customers_report = Reports.get({ //Reports.customer_report({
monthReport: selectedPeriod
}, function(result ){
var data = result.customers;
$scope.tableParams.total(data.length);
var orderedData = params.sorting() ? $filter('orderBy')(data, params.orderBy()) : data;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
});
}
and watching for filter change look like follow:
$scope.reportBillingPeriod = 0;
$scope.$watch('reportBillingPeriod', function(newValue, oldValue) {
$scope.tableParams.reload();
});
UPDATE 3
removed duplication of invocation getData
func,edited here
the issue was laid in $watch
of reportBillingPeriod
variable,so in order to prevent second data upload we have to check how values is changed, like here
$scope.reportBillingPeriod = defaultValue;
$scope.$watch('reportBillingPeriod', function(newValue, oldValue) {
//this how we prevent second call
if (newValue!=oldValue)
$scope.tableParams.reload();
});
来源:https://stackoverflow.com/questions/26205534/ng-table-not-rendering-new-data-when-reloading-request