D
D
Danil Chekalin2013-11-19 14:33:02
Angular
Danil Chekalin, 2013-11-19 14:33:02

AngularJS, synchronization of data from the server and model after "Actions"

I am implementing an admin panel for a project. List of materials (in this case, "news") in the form of a table with two "actions" (edit and remove).

dea26565988d7a6416df6c2c55dc888a.jpg

View:

<tr ng:repeat="item in items">
        <td>{{ item.news_id }}</td>
        <td>{{ item.news_preview|truncate:20 }}</td>
        ...
        <td>
            <i class="square small inverted edit icon" ng:click="editAction(item)"></i>
            <i class="square small inverted remove icon" ng:click="deleteAction(item)"></i>
        </td>
    </tr>


The model (although it's not a model, but for now in the learning process, it's usually called the Factory), is aligned with the methods of the Laravel 4 RESTful controller:
angular.module('backendApp.services')
    .service('NewsModel', function ($resource, PATH_API) {

        return $resource(PATH_API + 'news/:param1/:param2', {}, {
            index  : { method: 'GET', isArray: true },
            create : { method: 'GET', params: {param1: 'create'} },
            store  : { method: 'POST' },
            show   : { method: 'GET', params: {param1: '@id'} },
            edit   : { method: 'GET', params: {param1: '@id', params: 'edit'} },
            update : { method: 'PUT', params: {param1: '@id'} },
            destroy: { method: 'DELETE', params: {param1: '@id'} }
        });

    });


Controller:
angular.module('backendApp.controllers')
    .controller('NewsListController', function ($rootScope, $scope, $routeSegment, $location, PATH_API, NewsModel, $notification) {

        $scope.items = NewsModel.index();

        $scope.deleteAction = function (item) {
            var selfItem = item,
                lastData = null;

            NewsModel.destroy({param1: selfItem.news_id}, function () {

                // "Мягко" удаляем запись. Без ресета данных модели.
                $scope.items.splice($scope.items.indexOf(selfItem), 1);

                // Получаем с сервера актуальное состояние и сравниваем.
                // Синхронизируем, если есть различия.
                lastData = NewsModel.index(function () {
                    if (!angular.equals($scope.items, lastData)) {
                        // Запускаем нотификацию
                        $notification.info('Синхронизация данных');
                        // Обновляем модель (hard reset model).
                        $scope.items = lastData;
                    }
                });
            });
        };
    });


By the time I wrote, I had already resolved the issue. However, another question arose.
Situation: at one moment two people edit the content, one adds News (with ID 7) and deletes with ID 5 for example. And the other does nothing and weighs on the table. Naturally, he doesn’t have up-to-date information and he starts deleting News with ID 3. (Implemented, where the hard reset model comment is) He “pulls” (not just the deleted elements are sold, but in general everything is deleted and rendered according to a new one) table because the model was completely replaced due to the fact that angular.equals($scope.items, lastData) returned false . Also, the case is not implemented when clicking on the deletion of News that has already been deleted. I think the idea is clear. Who solves this kind of problem? Google don't even know how to ask a question.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
Z
zloyusr, 2013-11-19
@dakiesse

alexiusp , I think the author was interested in the issue of data synchronization between several clients.
The question is really not simple, and first of all you need to decide whether you need it. Is it really critical in your application that two clients can edit the same record at the same time? If so, then I recommend that you read articles on the topic "parallel editing" (you can start right with Habrahabr'a ), as well as the ShareJS library .

A
Aleksei Podgaev, 2013-11-19
@alexiusp

Concerning synchronization at removal.
Option 1: darken or even hide the table area for the duration of the synchronization, so that "jerking" does not cause questions from the user
Option 2: instead of $scope.items = lastData; bypass the array, compare the values ​​received from the server with the existing ones and change, if there is anything.
Obviously, the second option is more expensive in terms of resources and generally not very attractive. If two users are sitting at the same time and two rows in the table have changed, it will be beautiful, but if there are more users and more changes, jerking will still occur due to a radical change in the content.
You can, in extreme cases, try to do not a radical equalization of arrays, but a line-by-line one - maybe this will smooth the picture a little.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question