функция слайса в JavaScript не работает для разбиения на страницы

0

Я делаю приложение Todo с помощью Angularjs. Я попытался использовать разбиение на страницы, которое будет отображать только 5 todos на страницу. Я мог бы добавить разбивку на страницы, но функция slice не работает в списке todos.

Он говорит, что функция среза не определена. Я получил причину своего неопределенного поведения. Это связано с тем, что список задач не входит в область видимости, и мне почему-то нужно выводить список дел, чтобы он был доступен для следующей функции. Но с нулевым успехом я мог бы сделать это возможным.

Это мой код контроллера:

todoApp.controller('mainController', ['$scope', '$filter', 'Todos', function($scope, $filter, Todos) {
    $scope.formData = {};
    $scope.loading = true;
    $scope.count = 0;

    $scope.filteredTodos = [];   
    $scope.currentPage = 1;
    $scope.numPerPage = 5;
    $scope.maxSize = 5;

    // GET =====================================================================
    // when landing on the page, get all todos and show them
    // use the service to get all the todos
    //$scope.todos = [];
    Todos.get()
        .success(function(data) {
            $scope.todos = data;
            // for(var i = 0; i < data.length; i++) {
                //$scope.todos.push(data[i]);
            //}
            $scope.loading = false;
            angular.forEach($scope.todos, function(todo){
                todo.formattedCreatedOn = $filter('date')(new Date(todo.createdOn),'MMM dd, yyyy  -  hh:mm a');
            });
        });

     $scope.$watch('currentPage + numPerPage', function() {
        var begin = (($scope.currentPage - 1) * $scope.numPerPage);
        var end = begin + $scope.numPerPage;

        $scope.filteredTodos = $scope.todos.slice(begin, end);
    });
}]);

$ Scope.todos, мне нужно как-то выставить его за пределы его текущего объема. Поэтому он недоступен для function $scope.todos.slice(begin,end).

Другое дело, что функция $ watch вызывается перед сборкой списка todos. Это связано с тем, что к тому времени, когда служба извлекает todos из db, $ watch уже вызывается в списке с длиной 0 и, следовательно, не работает дальше.

Я даже пытался использовать код в этой ссылке.

  • 0
    Почему вы смотрите эти переменные? Я не понимаю Просто добавьте обычный метод области видимости, который вызывается после нажатия на директиву paginator.
  • 0
    Я сделал это, как показано в плункерной ссылке, которую я только что прикрепил. Но это не удалось. Пожалуйста, помогите мне больше в этом.
Теги:
pagination
slice

4 ответа

0

Попробуйте установить $scope.$watch внутри обратного вызова .success:

Todos.get()
    .success(function(data) {

        $scope.$watch('currentPage + numPerPage', function() {
          var begin = (($scope.currentPage - 1) * $scope.numPerPage);
          var end = begin + $scope.numPerPage;

          $scope.filteredTodos = data.slice(begin, end);
        });
    });
});
0

Я добавил следующий код:

todoApp.filter('limitFromTo', function(){
    return function(input, from, to){
        return (input != undefined)? input.slice(from, to) : '';
    }
});

и использовал этот фильтр здесь:

ng-repeat="todo in todos | limitFromTo:(currentPage-1)*itemsPerPage:(currentPage*itemsPerPage)"

Вместо использования функции limitTo, которая использовала такие параметры, как itemsPerPage и (currentPage-1)*itemsPerPage, я использовал limitFromTo, мой собственный фильтр, который будет иметь два смещения в массиве, например, если currentPage равен 1, тогда он будет показывать записи из 0- 5, для 2 6-10 и так далее. Фильтр limitTo имеет такие параметры, как количество записей, которые нужно показать, и от какого индекса или смещения, чего я не хотел, и, следовательно, использовал limitFromTo в соответствии с моими потребностями. И это сработало.

0

Я думаю, вы должны заставить его работать, сначала определяя $ scope.todos (есть строка комментариев, почему она закомментирована?), А затем, проверяя, будут ли границы "начинаться" и "заканчиваться" в пределах размера ваших todos -array. Вы можете получить несколько элементов, которые не могут быть делятся на ваш numPerPage, поэтому в любом случае вам нужно будет проверить, не превышает ли конец размер вашего массива и соответственно его установить, если это так.

$scope.$watch('currentPage + numPerPage', function() {
    var begin = (($scope.currentPage - 1) * $scope.numPerPage);
    var end = begin + $scope.numPerPage;

    if(end>=$scope.todos.length)
      end = $scope.todos.length-1;

    $scope.filteredTodos = $scope.todos.slice(begin, end);
});

Дай мне знать, если это трюк.

Приветствия, Кристоф

  • 0
    Это все еще не работает.
  • 0
    Хорошо, что происходит? Он все еще жалуется на то, что $ scope.todos не определено в $ scope.watch?
Показать ещё 2 комментария
0

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

https://docs.angularjs.org/api/ng/filter/limitTo

пример:

angular.module('myApp',[]).controller('TodosController',
function TodosController($scope) {
 $scope.todos = [
  {name:"todo1"},
  {name:"todo2"},
  {name:"todo3"},
  {name:"todo4"},
  {name:"todo5"},
  {name:"todo6"},
  {name:"todo7"}
 ];
  
 /* Rows per page */
 $scope.limit = 3;
 /* We start displaying at item 0 */
 $scope.begin = 0;
}
                                      
);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>

<div ng-app="myApp" ng-controller="TodosController">
  
 todos (page {{begin/limit}}):
 <ul>
   <li ng-repeat="todo in todos | limitTo:limit : begin">{{todo}}</li>
 </ul>

 <button ng-click="begin = 0">&lt;&lt;</button>
 <button ng-click="begin = begin>=limit ? begin - limit:0">&lt; previous page</button>
 <button ng-click="begin = begin + limit">next page &gt; </button>
</div>
  • 0
    Здесь это выйдет за пределы моих задач, не так ли? Как и в случае с вашим делом, есть 7 задач, которые поместятся в 2 страницах по 5 в каждой. Если я попытаюсь перейти на следующую страницу, она пойдет и ничего мне не покажет, верно? Поправьте меня если я ошибаюсь. И если это так, как это остановить?
  • 0
    Я не уверен, что понимаю ваш вопрос. Это всего лишь демонстрация "LimitTo", неполной системы нумерации страниц. Я немного отредактирую это. В любом случае, используя limitTo, вы можете свернуть свою собственную систему нумерации страниц, просто изменив модель начала.
Показать ещё 10 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню