Вызвать JSON после того, как пользователь сделал фильтр - PullRequest
0 голосов
/ 08 февраля 2019

У меня очень большой JSON (5000 ключей с 5 значениями в каждой), и я хочу знать, есть ли лучший способ улучшить производительность этого.Например, я использую AngularJS с Backend в Drupal 7.

My View

  <ul class="list-group border-0">
                 <form class="form-inline m-3">
                    <div class="col-sm p-0 float-left w-50">
                      <label class="col-form-label text-primary lead form-group" for="inputsm" for="name" for="inlineFormInput">Year: </label>
                    </div>
                    <div class="col-sm p-0 float-left w-50">
                      <input class="form-control" ng-model="searchYear"/> 
                    </div>
                 </form> //I have more filters than this one...
                  <li class="list-group-item border-0" ng-repeat="item in filterData = (informes | filter:{year: searchYear}) | limitTo:10:10*(currentPage-1)">
                     <div class="wrapper">
                        <div class="informes">
                          <a href="#!/node-informes" ng-value="{{item.nid}}">
                            <p class="text-left">
                               <p ng-click="nodeID(item)">{{item.title}}</p>
                            </p>
                          </a>
                        </div>
                    </div>
                </li>      
              </ul>

И JS

    informes.factory('InformesFtry', ['$http', function ($http) {
  return {
      getAll: function () {
        return $http.get('https://myjsonurl/json');
      }
   };
}]); 

 informes.controller('InformesCtrl', ['drupal', '$rootScope', '$scope', '$http', 'InformesFtry', '$localStorage', function(drupal, $rootScope, $scope, $http, InformesFtry, $localStorage) {

    InformesFtry.getAll().success(function(rows) {
        $scope.informes = (rows, function(items) {
            return rows.nodes;
        })();
        $scope.output();
    });

    $scope.loading = true;
    $scope.loaded = false;
    $scope.totalItems = [];
    $scope.currentPage = 1;
    $scope.itemsPerPage = 10;

    $scope.output = function() {
        $scope.loading = false;
        $scope.loaded = true;
        $scope.totalItems = $scope.informes.length;
        $scope.viewby = 10;
        $scope.maxSize = 5;
        $scope.itemsPerPage = $scope.viewby;
        $scope.displayItems = $scope.informes.slice(0, 10);
        var currentPage = $scope.currentPage;

        $scope.setItemsPerPage = function(num) {
            $scope.itemsPerPage = num;
            $scope.currentPage = 1;
        }

        $scope.pageChanged = function() {
            var startPos = ($scope.currentPage - 1) * 10;
            $scope.displayItems = $scope.informes.slice(startPos, startPos + 10);
        };

    }

    $scope.nodeID = function(item) {
     $localStorage.nid = item.nid;
     console.log("nodeID");
    }
}]);

Я пытался из моего Backend отделитьэти файлы и итерируются из контроллера, но для производительности лучше искать в JSON после того, как запрос сделан из представления, как обратное тому, что я делаю.Поиск везде, но я не смог найти возможное разрешение.

Я думал об использовании json после того, как был сделан запрос из представления.

Я не знаю, как этого добиться.Разделение файлов даст мне тот же результат, если только не будет способа сделать фильтр перед вызовом JSON.Заранее спасибо.

1 Ответ

0 голосов
/ 08 февраля 2019

Да, есть абсолютно способы сделать это более производительным.Вы можете улучшить производительность, переместив логику фильтра с вашего ng-repeat на контроллер.Затем обновите список элементов, которые вы хотите повторить в вашем контроллере.Вот отличная статья, в которой говорится именно об этом.

https://toddmotto.com/use-controller-filters-to-prevent-digest-performance-issues/

Краткое объяснение того, почему это помогает, заключается в том, что ваш ng-repeat будет постоянно обрабатываться для изменений в циклах дайджеста, даже еслизначения вокруг него никогда не менялись, это означает, что он фильтрует эти 5000 записей каждый раз.Вы можете переместить свою логику фильтрации в контроллер и затем запускать ее при обновлении списка, используя ng-change в своих фильтрах (например, ввод года).

Таким образом, реализация будет выглядеть следующим образом:

JavaScript:

$scope.updateData = function(){
    var filteredData = $filter('filter')($scope.informes, {'year': $scope.searchYear});
    filteredData = $filter('limitTo')(filteredData, 10, (10 * (currentPage - 1)));
    $scope.filteredData = filteredData;
}

HTML:

<!-- Your Inputs should have ng-change -->
<input class="form-control" ng-model="searchYear" ng-change="updateData()"/> 

<!-- Remove filters from html and loop over your filtered list -->
<li class="list-group-item border-0" ng-repeat="item in filteredData">

Редактировать: добавлены дополнительные пояснения и примеры изменений кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...