#5 Пишем Trello на AngularJS. Часть 5.

poster
В этом уроке мы продолжаем реализовывать Trello, а именно селект для выбора списка и директиву для закрытия формы редактирования.
Понравилось? Поделитесь с друзьями!
Понравилось?
Поделитесь с друзьями!
Комментарии
Текст видео

Всем привет. Сегодня у нас заключительное видео по Trello. Мы будем добавлять select во время редактирования, для того, чтобы менять список в котором находится карточка. Также напишем простую директиву.

Давайте добавим select к нашей форме

<div ng-if="cardCtrl.isEditing">
  <form ng-submit="cardCtrl.updateCard(card)">
    <input type="text" ng-model="cardCtrl.editingCard.description">
    <select class="select-list"
            ng-model="cardCtrl.editingCard.list_id"
            ng-change="cardCtrl.updateCard()"
            ng-options="list.id as list.listName for list in listsCtrl.lists">
      <option value="-- choose list --"></option>        
    </select>        
  </form>
</div>

В select указываем ng-model редактируемой карточки. Мы используем id как value, а в лейблах мы будем выводить listName. Мы проходим циклом по listsCtrl.lists.

Давайте посмотрим. Как мы видим, у нас появился select с выбором списка.

По change у нас вызывается updateCard. В него нам ничего передавать не надо так как мы работаем с this.editingCard, поэтому мы можем удалить аргумент updateCard из ng-submit.

Давайте добавим еще одно присвоение в updateCard. Мы обновляем list_id из updatingCard.

service.updateCard = function (updatingCard) {
  var card = _.findWhere(cards, { id: updatingCard.id })
  card.description = updatingCard.description;
  card.list_id = updatingCard.list_id;
}

Теперь если мы выбираем другой список, то карточка сразу же перемещается в другой список. Выбор choose list нам особо не нужен так как у нас карточка всегда находится в каком-то списке.

Теперь давайте напишем директиву. Эта директива будет, когда у нас активирован input, и если мы будем нажимать escape, то форма редактирования карточки будет закрываться.

Давайте создадим папку directives. В ней создадим closeEditing.js

angular.module('app').directive('closeEditing', function () {
  return {
    link: function (scope, element, attrs) {
      console.log('LINK');
    }
  }
})

Добавим директиву в список скриптов и повесим эту директиву на наш input.

<input type="text"
       close-editing
       ng-model="cardCtrl.editingCard.description">

Не забываем, что close-editing нужно писать через тире, а не через camelCase.

Когда мы нажимаем edit наша директива link отрабатывает.

Теперь мы хотим создать scope и передать туда переменную isEditing.

angular.module('app').directive('closeEditing', function () {
  return {
    scope: {
      isEditing: '='
    },
    link: function (scope, element, attrs) {
      console.log('LINK');
    }
  }
})

Это значит, что у нас будет двухсторонний дата биндинг. Теперь мы должны добавить isEditing в качестве атрибута.

<input type="text"
       close-editing
       is-editing="cardCtrl.isEditing"
       ng-model="cardCtrl.editingCard.description">

Теперь повесим евент keyUp и будем отслеживать нажатие escape.

angular.module('app').directive('closeEditing', function () {
  var KEYS = {
    ESCAPE: 27
  };
  return {
    scope: {
      isEditing: '='
    },
    link: function (scope, element, attrs) {
      element.on('keyup', function (e) {
        if (_.isEqual(e.keyCode, KEYS.ESCAPE)) {
          scope.isEditing = false;
          scope.$apply();
        }
      })
    }
  }
})

Также мы добавили константу KEYS, которая хранит ключи букв, которые мы нажимаем. В данном случае нас интересует клавиша escape. Ее код 27. Дальше мы проверяем, что keyCode нажатой клавиши равняется KEYS.ESCAPE. Если мы нажали кнопку escape, то мы меняем значение переменной isEditing и закрываем этим самым форму редактирования.

Также не нужно забывать, что keyup - это метод jqLite и angular о нем ничего не знает. Поэтому нам нужно вызвать $scope.apply();

Теперь если мы редактируем карточку и нажимаем escape, то у нас закрывается форма редактирования. Вот так с помощью простой директивы мы реализовали то, что все наши карточки имеют форму редактирования, которую можно закрыть.

Впринципе мы закончили реализовывать Trello. Мы реализовали render карточек, вывод и создание списка, создание карточек в этом списке, удаление списков и карточек, редактирование карточек и даже select, который позволяет выбирать другой список.

Только зарегистрированные пользователи могут оставлять комментарии.  Войдите, пожалуйста.
Zato Prosto
4 месяцев назад
А можно подробнее про scope.$apply() в дирктиве? Непонятно, все-таки, зачем это писать там. JQLite - это плюха ангуляра. Но даже если и впрямь общего контекста у них нет, то мы ведь явно указали новое значение для isEditing. Как ангуляр может его не видеть??
monsterlessons
4 месяцев назад
jqlite это просто обрезанное jQuery. Хоть оно и запаковано внутри ангуляра но никак им не отслеживается. Для запуска жизненного цикла заново и обновления значений мы используем scope.$apply().
Zato Prosto
4 месяцев назад
Буду знать. Еще раз спасибо за урок и подробные объяснения.