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

AngularJs Rendering table, why only fires 1 time?

There is this table:

<table class="bordered">
            	<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>
                            <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>
            			<!-- Delegate target. -->

There is a table render function
// Рендер таблицы
            renderTable: function ($scope, 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)
Sergey, 2014-04-20

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:


.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) {

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

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