سؤال

I have created a table and I am using http to load the data in the tables. So, in every click, my table data is changing, but I don't see the updated data in the table. I had created a sample Plunker for the reference. In my project, WHen I click on Reload New Data, the data in table get's changed, but after 2-3 click it doesn't change. DId anyone know, how to fix it..

هل كانت مفيدة؟

المحلول

It is a problem with the ngTable directive. It updates only when data.length changes. Take a look at this plunk. I set $scope['tableParams1'] to null and inside the $timeout I set the new data. This forces angularJs to do a new cycle. So in the first cycle the ngTable sees the data.length changed to 0 and in the new cycle the ngTable sees the data.length changed again. If you don't use the $timeout, the ngTable will see that the data.length remains the same as before and won't do nothing.

نصائح أخرى

With some trial and error I found a seemingly better solution to the issue than indicated in the plunkrs. For clarity, I am using $resource in a service to fetch my data. When I add a record via a modal, at first it wouldn't upload the ng-table after closing the modal. I figured out a way that works for me:

// Get data from factory
var data = dataFactory.query();

//Use promise to load data to table, note the replacing of the second tableParams 
//object parameter with a function
data.$promise.then(function (data){
    $scope.tableParams = new ngTableParams({
        page: 1,            // show first page
        count: 10,
        sorting: {
            name: 'asc'
        },
        filter: {
            name: undefined             
        }
    }, resetTableParams()
    );
});

//The function that replaces the tableParams param
var resetTableParams = function(){
    return {
        total: data.length,
        getData: function($defer, params) {
            var filteredData = params.filter() ? $filter('filter')(data, params.filter()) : data;
            var orderedData = params.sorting() ? $filter('orderBy')(data, params.orderBy()) : filteredData; 

            params.total(orderedData.length);
            $defer.resolve($scope.data = orderedData.slice((params.page() -1) * params.count(), params.page() * params.count()));           
            }
    }
}

//A method to update the table that can be called when closing a modal
var updateTable = function(){
    data = dataFactory.query();
    data.$promise.then(function (data){
        $scope.tableParams.reload();
    });
}

// Add table row to table in modal and call updateTable() on closing modal
$scope.addRow = function(){
    var modalInstance = $modal.open({
        templateUrl: 'resources/partials/newrecord.html',
        controller: NewRecordModalCtrl
    })

    modalInstance.result.then(function(){
        updateTable();
    });
}

Unfortunately, I can't give a clear explanation as to why this works and other methods don't. For instance, if you would not use the resetTableparams() function but leave it hardcoded, the table does not update. Somehow, Angular's digest cycle likes this better :) If somebody has a good explanation, please share!

You can directly use the provided method $scope.tableParams.reload();

I'm not sure about the exact cause of the incorrect incrementing, but the problem here may be more due to the approach. You should attach the count to the scope via $scope.count, and then use the ng-click directive to increment it: <button type="button" ng-click="count++;".

It would also make it easier for you/others to read and debug if you externalized the $scope.tableParams and the data from $scope.table1 conditional thing:

$scope.count = 0;

var dataCollections = [
    [//.. first collection],
    [//.. second collection],
    [//.. third collection],
    [//.. fourth collection]
];

$scope.data = dataCollections[0];

$scope.$watch('count', function () {
    $scope.data = $scope.count < 4 ? dataCollections[$scope.count] : dataCollections[3];
});

I'm also not sure what you've got going on there with the $compile inside of the controller. It might make your task easier if you investigated some stuff about writing Angular controllers before delving into using a third-party module.

I was working on ng-tables with dynamic data as well (adding/removing),
I was using an ajax call to make changes to the database, and the success: function() {} property make changes to the tableParams
but changes wouldn't show on the page unless i refreshed it, with a few console.log()'s, I found out that the success: function() {} actually never executes
but there's another function that always executes, complete: function() {} I know it's logically wrong to put the code that's supposed to work only after a successful call into complete: function() {} but if my success: function isn't working, this fix isn't that bad, especially knowing that the change is always successfully made to the database
it's strange because the success call works on other pages of the website, but it doesn't on some others. EDIT:
well, this fix still doesn't solve the problem when the length of the data doesn't change "editing the text in the data" as mentioned above,, frustrating...

$.ajax({
        type: "POST",
        url: /*some url*/,
        data: JSON.stringify({ /*some variable*/ }
        }),
        contentType: "application/json; charset=utf-8",
        dataType: "Json",
        success: function () {  // would never execute even if it's a successful call
            console.log("success"); 
        },
        error: function() {  // optional, personally didn't try it
            console.log("error"); 
        }
        complete: function () {  //always executes regardless of the result
            console.log("complete"); 
        }
    });

To solve the issue, make sure you have set the ng-controller="yourController" only once in your page.

Code below will not update data:

<div ng-controller="yourController">
  <table ng-table = "tableParams" ng-controller = "yourController">
  </table>
</div>

Solve the issue by removing extra ng-controller in your html page:

<div ng-controller="yourController">
  <table ng-table = "tableParams">
  </table>
</div>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top