2015-11-26 1 views
0

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

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

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

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 и, следовательно, не работает дальше.

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

+0

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

+0

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

ответ

0

Я думаю, вы должны заставить его работать, сначала определяя $ scope.todos (есть строка комментариев, почему она закомментирована?), А затем, проверяя, будут ли границы «начинаться» и «заканчиваться» в пределах размер вашего массива todos. Вы можете получить несколько элементов, которые не могут быть делятся на ваш 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); 
}); 

Сообщите мне, если это трюк.

Cheers, Кристоф

+0

Он все еще не работает. –

+0

Хорошо, что происходит? Он все еще жалуется на то, что $ scope.todos не определено в $ scope.watch? –

+0

Нет, я не жалуюсь на это. Но он вообще не отображает никаких записей только для табуляции: Первый Предыдущий 1 Следующий Последний. Это оно. –

0

Если отобразить список Todos, я полагаю, что есть нг-повтор в шаблоне. Вы можете быть заинтересованы в 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

Здесь он выйдет за пределы моих todos, не так ли? Так же, как и ваше дело, есть 7 todos, которые будут вписываться в 2 страницы по 5 штук. Если я попытаюсь перейти на следующую страницу, это пойдет и покажет мне ничего, правильно? Поправьте меня если я ошибаюсь. И если это так, как остановить это? –

+0

Я не уверен, что понимаю ваш вопрос. Это всего лишь демонстрация «LimitTo», неполной системы разбиения на страницы. Я немного его отредактирую. В любом случае, используя limitTo, вы можете свернуть свою собственную систему разбиения на страницы, просто изменив модель «begin». – BiAiB

+0

Я пробовал этот путь, как показано вами. Но это просто изменение номера страницы: 'todos (page 0)' здесь, но не записи, которые он показывает на странице. То есть изменяется только номер страницы, а не записи в списке при нажатии следующей и предыдущей. –

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.$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); 
     }); 
    }); 
}); 
Смежные вопросы