Разбивка на страницы по неделям — AngularJS

Я пытаюсь разбить список событий (используя ng-repeat) по неделям в AngularJS. У меня работает настраиваемый фильтр, который отображает события только за текущую неделю, но я пытаюсь добавить функциональность для просмотра будущих и прошлых недель.

Вот фильтр, который я использую для списков событий:

$scope.week = function(item) {
    var weekStart = moment().startOf('week');
    var weekEnd = moment().endOf('week');
    var eventTime = moment(item.jsdatetime);
        if (eventTime >= weekStart && eventTime <= weekEnd) return true; 
            return false;
};

Я попытался использовать ng-click для вызова функции, которая использует moment.js для .add(7, 'days'); к переменным weekStart и weekEnd, но, похоже, не может заставить его работать.

Любая помощь будет оценена по достоинству.

Вот CodePen с базовой функциональностью: http://codepen.io/drewbietron/pen/xbKNdK


person Drewbietron    schedule 11.11.2014    source источник
comment
Не могли бы вы создать базовый плунжер для демонстрации того, что делается? Вот шаблон для начала: plnkr.co/edit/TkONdJqtD6nSg6s0Da59?p=info причина в том, что нам нужно увидеть больше кода, чтобы помочь вам.   -  person SoluableNonagon    schedule 11.11.2014
comment
@EliteOctagon - я добавил пример CodePen в свой исходный пост   -  person Drewbietron    schedule 11.11.2014


Ответы (2)


moment() всегда возвращает текущую дату/время.

Вам нужно сохранить ссылку на него в переменной, а затем использовать ее для манипуляций.
(и, поскольку у вас есть другие переменные, зависящие от нее, я бы создал функцию, которая устанавливает все эти переменные сразу)

Итак, в контроллере я изменил верхнюю часть на

var currentDate,
    weekStart,
    weekEnd,
    shortWeekFormat = 'MMMM Do';

function setCurrentDate(aMoment){
  currentDate = aMoment,
  weekStart = currentDate.clone().startOf('week'),
  weekEnd = currentDate.clone().endOf('week')
}

// initialize with current date
setCurrentDate(moment());

// use these methods for displaying 
$scope.currentWeek = function(){ return currentDate.format(shortWeekFormat); }; 
$scope.currentWeekStart = function(){ return weekStart.format(shortWeekFormat); };
$scope.currentWeekEnd = function(){ return weekEnd.format(shortWeekFormat); };

Затем создайте два метода для перехода на следующую/предыдущую неделю.

$scope.nextWeek = function(){
  setCurrentDate(currentDate.add(7,'days'));
};
$scope.prevWeek = function(){
  setCurrentDate(currentDate.subtract(7,'days'));
};

(moment.js реализует valueOf, поэтому вы можете проводить прямое сравнение)
И, наконец, измените фильтр недели, чтобы фактически сравнивать даты (используя .isSame(), .isBefore() и .isAfter()) вместо объектов момента (что было неправильно, так как нельзя проводить прямое сравнение пользовательских объектов)

$scope.week = function(item) {
    var eventTime = moment(item.jsdatetime);

    if ((eventTime.isSame(weekStart) || eventTime.isAfter(weekStart))&& 
        (eventTime.isSame(weekEnd) || eventTime.isBefore(weekEnd))) return true; 

    return false;
};

$scope.week = function(item) {
    var eventTime = moment(item.jsdatetime);

    return (eventTime >= weekStart && eventTime <= weekEnd);
};

(вы также, скорее всего, хотите ng-repeat в li элементах, а не ul)

Демонстрация http://codepen.io/gpetrioli/pen/QwLRQB

person Gabriele Petrioli    schedule 11.11.2014
comment
Я использую фильтр GroupBy github.com/a8m/angular-filter#groupby и вызов вложенного ng-repeat для дней, чтобы я мог получить их в представлении календаря и показать дни только один раз. Поэтому я вызываю начальный ng-repeat на ul, а затем вложенный на li. - person Drewbietron; 11.11.2014
comment
Я понимаю. тогда вы можете игнорировать эту часть ответа :) - person Gabriele Petrioli; 12.11.2014
comment
Ха, я должен был переключиться на CodePen — мне пришлось собрать суперупрощенную версию данных, которые я повторяю, и пропустить эту часть. Я ценю помощь, хотя! - person Drewbietron; 12.11.2014

Переменные weekStart и weekEnd не существуют вне области действия week(item). Если вы используете ngClick для вызова функции, которая пытается изменить эти переменные, она просто вернет значение undefined. Я не знаю, каков ваш макет, но я бы вытащил эти две переменные за пределы функции недели и сделал их переменными $scope.

Кроме того, я бы попросил ngClick вызвать функцию, которая изменит две переменные $scope (либо прибавит 7, либо вычитает 7 в зависимости от того, в каком направлении вы хотите двигаться).

$scope.weekStart = moment().startOf('week');
$scope.weekEnd = moment().endOf('week');

$scope.week = function(item) {
    var eventTime = moment(item.jsdatetime);
    if (eventTime >= $scope.weekStart && eventTime <= $scope.weekEnd) return true; 
      return false;
    };

$scope.update= function(direction) {
    $scope.weekStart.add(direction, 'days');
    $scope.weekEnd.add(direction, 'days');
}

И создайте две кнопки в своем представлении:

<a href="#" ng-click="update(-7)">Previous week</a>
<a href="#" ng-click="update(7)">Next week</a>
person nairys    schedule 11.11.2014
comment
Спасибо за помощь. Как мне вызвать функцию ng-click, которая применяется к этому конкретному фильтру? - person Drewbietron; 11.11.2014
comment
Извините, я неправильно понял, как вы использовали неделю. Теперь, когда я посмотрел на код, вы не стали бы использовать ngClick для вызова функции, которая вызывает функцию недели, поскольку неделя — это просто ваш фильтр. Вместо этого я бы изменил weekStart и weekEnd на переменные $scope в фильтре недели. В функции ngClick вы можете манипулировать переменными $scope.weekStart и $scope.weekEnd. У меня проблемы с codepen, поэтому я не могу показать пример прямо сейчас. Однако это должно быть все, что вам нужно сделать. Я обновил свой ответ небольшим образцом кода. - person nairys; 11.11.2014
comment
Это отлично работает, чтобы изменить неделю, спасибо. Любая идея, как я могу отключить щелчок для выхода за пределы определенной даты - скажем, в прошлом? - person Drewbietron; 11.11.2014
comment
Вы можете попробовать использовать директиву ngDisabled и проверить неделюStart по текущей дате (или какой-либо другой дате, которую вы не хотели бы проходить). редактировать: Чтобы уточнить, я имею в виду, попробуйте использовать ngDisabled в тегах привязки в представлении. - person nairys; 11.11.2014