
Всем привет. Сегодня мы продолжаем делать Trello, а именно удаление и обновление карточек.
Для начала добавим метод deleteCard.
<div class="card"
ng-repeat="card in listCtrl.getCards(list)">
{{card.description}}
<div ng-click="cardCtrl.deleteCard(card)"
class="remove-small remove-card hand">
</div>
</div>
cardCtrl у нас нет. Зачем он нам? Когда мы работаем с конкретной карточкой, а именно с ее удалением и обновлением, логично, чтобы эти екшены находились в контроллере отдельной карточки. Для этого давайте добавим ng-controller cardCtrl.
<div class="card"
ng-controller="cardCtrl as cardCtrl"
ng-repeat="card in listCtrl.getCards(list)">
{{card.description}}
<div ng-click="cardCtrl.deleteCard(card)"
class="remove-small remove-card hand">
</div>
</div>
и создадим cardCtrl.js
angular.module('app').controller('cardCtrl', function (cardFactory) {
this.deleteCard = function (card) {
cardFactory.deleteCard(card);
}
});
Не забудьте добавить cardCtrl в index.html.
Добавим метод deleteCard, который будет получать карточку и вызывает метод из cardFactory.
Добавим метод deleteCard в cardFactory.
service.deleteCard = function (card) {
return _.pull(cards, card);
}
Методом _.pull удаляем карточку из массива.
Давайте попробуем. У нас появились на карточках крестики и при нажатии карточка у нас исчезает.
Давайте теперь реализуем обновление.
<div class="card"
ng-controller="cardCtrl as cardCtrl"
ng-repeat="card in listCtrl.getCards(list)">
{{card.description}}
<div ng-click="cardCtrl.editCard(card)"
class="edit-small edit-card hand">
</div>
<div ng-click="cardCtrl.deleteCard(card)"
class="remove-small remove-card hand">
</div>
</div>
и добавим метод editCard в контроллер
this.isEditing = false;
this.editingCard = null;
Для начала добавим переменную isEditing в контроллер. Эта переменная будет показывать в каком состоянии у нас карточка. Если isEditing true, значит мы сейчас редактируем карточку. В переменной editingCard мы будем хранить данные по карточке, которую мы редактируем.
this.editCard = function (card) {
this.isEditing = true;
this.editingCard = angular.copy(card);
}
Метод editCard принимает на вход карточку. Потом мы хотим сказать, что мы начали редактирование карточки, поэтому this.isEditing = true, а в editingCard записать карточку, которую мы начали редактировать.
Зачем делать angular.copy? Если мы сделаем какие-то изменения с карточкой и захотим их откатить, мы можем просто удалить editingCard. Если бы мы делали это ссылкой на карточку, то удаление карточки во время редактирования, привело бы к удалении карточки вообще из нашего массива карточек.
Теперь давайте добавим логику с isEditing.
<div class="card"
ng-controller="cardCtrl as cardCtrl"
ng-repeat="card in listCtrl.getCards(list)">
<div ng-if="!cardCtrl.isEditing">
{{card.description}}
<div ng-click="cardCtrl.editCard(card)"
class="edit-small edit-card hand">
</div>
<div ng-click="cardCtrl.deleteCard(card)"
class="remove-small remove-card hand">
</div>
</div>
</div>
Этот блок мы обернули в ng-if. Он будет показываться только если мы не в режиме редактирования.
Теперь при нажатии на кнопку edit у нас скрывается содержимое карточки. Сейчас у нас состояние карточки isEditing.
Теперь давайте добавим блок, который будет отображаться в режиме редактирования.
<div class="card"
ng-controller="cardCtrl as cardCtrl"
ng-repeat="card in listCtrl.getCards(list)">
<div ng-if="!cardCtrl.isEditing">
{{card.description}}
<div ng-click="cardCtrl.editCard(card)"
class="edit-small edit-card hand">
</div>
<div ng-click="cardCtrl.deleteCard(card)"
class="remove-small remove-card hand">
</div>
</div>
<div ng-if="cardCtrl.isEditing">
<form ng-submit="cardCtrl.updateCard(card)">
<input type="text" ng-model="cardCtrl.editingCard.description">
</form>
</div>
</div>
Мы добавили форму, которую мы показываем в момент редактирования карточки.
Давайте посмотрим в браузер. Когда мы нажимаем edit, у нас появляется форма с моделью editingCard.description. Теперь мы хотим, чтобы если мы что-то написали и нажали enter, что-то происходило.
Давайте опишем метод updateCard.
this.updateCard = function (card) {
cardFactory.updateCard(this.editingCard);
}
Давайте теперь опишем метод updateCard.
service.updateCard = function (updatingCard) {
var card = _.findWhere(cards, { id: updatingCard.id })
card.description = updatingCard.description;
}
В методе updateCard с помощью findWhere находим первую встретившуюся карточку с таким же id, как мы передали на вход. И меняем description в этой карточке.
Давайте попробуем. На самом деле у нас все работает, но так как мы не добавили закрытие формы, то нам и непонятно работает ли оно или нет. Давайте засетим переменную editingCard в null.
this.updateCard = function (card) {
cardFactory.updateCard(this.editingCard);
this.editingCard = null;
this.isEditing = false;
}
Как мы видим, форма теперь у нас закрывается и карточка редактируется.