N
N
nepster-web2014-04-20 22:38:13
JavaScript
nepster-web, 2014-04-20 22:38:13

AngularJs Rendering table, why only fires 1 time?

There is this table:

<table class="bordered">
                <thead>
                    <tr>    
                        <th>X</th>
                        <th>Y</th>
                        <th>Описание</th>
                        <th>Опции</th>
                    </tr>
                </thead>
                      
            	<tbody bn-delegate="tr | selectPoint( point )">
            		<tr ng-repeat="point in points">
            			<!-- Delegate target. -->
            			<td>{{ point.x }}</td>
            			<td>{{ point.y }}</td>
            			<td class="text-left">{{ point.desc }}</td>
            			<td>
                            <button class="icon edit confirm-delete" data-pointId="{{ point.pointId }}" data-desc="{{ point.desc }}" data-oldX="{{ point.x }}" data-oldY="{{ point.y }}" ng-click="openWindow('update', 'Редактировать точку', $event)">&nbsp;</button>
                            <button class="icon delete confirm-delete" data-pointId="{{ point.pointId }}" data-desc="{{ point.desc }}" data-oldX="{{ point.x }}" data-oldY="{{ point.y }}" ng-click="openWindow('delete', 'Удалить точку', $event)">&nbsp;</button>
                        </td>
            			<!-- Delegate target. -->
            		</tr>
            	</tbody>
                
            </table>

There is a table render function
// Рендер таблицы
            renderTable: function ($scope, points) {
                
                console.log(points);

        // I am the list of points to show.
        $scope.points = points;
                
        // I select the given point for display.
        $scope.selectPoint = function( point ) {
          $scope.selectedPoint = point;
        };

        // I determine which point (if any) has been selected
        // for display.
        $scope.selectedPoint = null;
            },

The application works as follows:
- there is a post request to the server and I get an object of all points, then I start rendering and draw a table. Everything is fine here.
- Next, for example, you need to add or remove a new point, after a successful action, I call renderTable($scope, points) again, but the table is not redrawn. At what I checked that the data in points comes correct.
Please tell me what is the problem?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Sergey, 2014-04-20
@nepster-web

in order for angular to understand that the data needs to be synchronized, you need to run at $scope either $apply (checks everything from $rootScope and down the hierarchy for changes) or $digest (updates the current and child scopes).
Basically what it should look like:

angular.module('app')

.factory('myApi', function ($http, $q) {
    return {
        list: function () {
             return $http.get('/points').then(function (response) {
                 return response.data;
             }, function () {
                 return $q.reject(); // произошла какая-то ошибка
             });
        },
        add: function (point) {
              return $http.post('/points', data).then(function (response) {
                   if (201 === response.status) { // если на сервере все сохранилось удачно
                        return response.data;
                   }

                   return $q.reject(); // как-то не удалось
              }, function () {
                   return $q.reject();
              });
        }
    }
})

.controller('MyCtrl', function ($scope, myApi) {
    myApi.list().then(function (points) {
        $scope.points = points;
    }); // было бы неплохо еще и ошибки как-то обрабатывать
    
    $scope.add = function () {
        myApi.add({...}).then(function (item) {
             $scope.points.push(item);
        });
    }
});

It's like an example. When $http completes the request, this service will start the digest cycle (since promises are tied to it, without calling $apply/$digest, promises will also not work immediately. So with this option, the scope will always be up to date.
If you have any then the action changes something in $scope by event - you need to manually call $scope.$apply or $scope.$digest.
// перед вызовом функции, переданной в $apply, 
// приложение синхронизирует свое состояние
// Это позволяет гарантировать то, что в на момент вызова функции
// отработают все ватчеры и внесут возможные изменения
// Это эдакий безопасный способ
$scope.$apply(function () {
    // chage scope
    $scope.points = []; // меняем...
});

If your collection is replaced by the same one, then the watcher will not work, the table will not be updated.

_
_ _, 2014-04-20
@AMar4enko

Maybe try $scope.apply?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question