nepster-web
@nepster-web

AngularJs Рендер таблицы, почему срабатывает только 1 раз ?

Есть вот такая вот таблица:
<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>


Есть функция рендера таблицы
// Рендер таблицы
            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;
            },


Приложение работает следующим образом:
- идет пост запрос на сервер и я получаю объект всех точке, далее запускаю рендер и рисую таблицу. Тут все нормально.
- Далее необходимо к примеру добавить или удалить новую точку, после успешного действия с нова вызываю renderTable($scope, points), однако таблица не перерисовывается. При чем я проверил, что данные в points приходят верные.

Подскажите пожалуйста в чем проблема ?
  • Вопрос задан
  • 3088 просмотров
Решения вопроса 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
что бы angular понял что данные нужно синхронизировать, нужно запустить у $scope либо $apply (проверяет на изменения все от $rootScope и вниз по иерархии) либо $digest (обновляет текущий и дочерние скоупы).

Вообще как это должно выглядеть:
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);
        });
    }
});


Это как пример. Когда $http завершит запрос, этот сервис запустит digest цикл (так как на него завязаны промисы, без вызова $apply/$digest промисы так же не отработают сразу. Так что при таком варианте скоуп всегда будет в актуальном состоянии.

Если у вас какое-то действие меняет что-то в $scope по событию - нужно вручную вызывать $scope.$apply или $scope.$digest. Причем лучше сделать так:
// перед вызовом функции, переданной в $apply, 
// приложение синхронизирует свое состояние
// Это позволяет гарантировать то, что в на момент вызова функции
// отработают все ватчеры и внесут возможные изменения
// Это эдакий безопасный способ
$scope.$apply(function () {
    // chage scope
    $scope.points = []; // меняем...
});


Если же у вас подменяется коллекция на ту же, то не отработает ватчер, не обновится таблица.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
AMar4enko
@AMar4enko
Может $scope.apply попробовать?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы