Добрый день. Столкнулся с проблемой, которая никак не поддается моему решению.
Во время написания достаточно легкой страницы я запихнул в класс карточки запросы к api и экземпляры другого класса, но это неправильно. Мне посоветовали использовать "слабое" связывание и перекинуть все запросы и их обработку в модуль index.js.
И вот тут случился тупик. Я не могу оторвать api из класса так, чтобы сайт продолжал работать. Могли бы вы помочь с решением данной задачи? Я уже 4 дня пытаюсь это сделать, но всё тщетно.
Card.js прикладываю
export default class Card {
constructor(
{ item, handleCardClick, handleLikeClick, handleDeleteConfirm }, cardSelector, userId, api ) {
this._name = item.name;
this._link = item.link;
this._likes = item.likes;
this._cardSelector = cardSelector;
this._handleCardClick = handleCardClick;
this._handleLikeClick = handleLikeClick;
this._handleDeleteConfirm = handleDeleteConfirm;
this._api = api;
this._id = item._id;
this._ownerId = item.owner._id;
this._userId = userId;
}
_getTemplate() {
const cardElement = document
.querySelector(this._cardSelector)
.content.querySelector('.card')
.cloneNode(true);
return cardElement;
}
handleDeleteCard() {
this._card.remove();
}
handleLikeCard() {
if (!this._cardLikeButton.classList.contains('card__like-button_active')) {
this._api
.like(this._id)
.then((item) => {
this._cardLikeButton.classList.add('card__like-button_active');
this._cardLikeCount.textContent = item.likes.length;
})
.catch((err) => {
console.log(err);
});
} else {
this._api
.removeLike(this._id)
.then((item) => {
this._cardLikeButton.classList.remove('card__like-button_active');
this._cardLikeCount.textContent = item.likes.length;
})
.catch((err) => {
console.log(err);
});
}
}
_setEventListeners() {
this._cardLikeButton = this._card.querySelector('.card__like-button');
this._cardDeleteButton = this._card.querySelector('.card__delete-button');
this._cardImage = this._card.querySelector('.card__image');
this._cardLikeButton.addEventListener('click', () => {
this._handleLikeClick();
});
this._cardDeleteButton.addEventListener('click', () => {
this._handleDeleteConfirm();
});
this._cardImage.addEventListener('click', () => {
this._handleCardClick(this._name, this._link);
});
}
generateCard() {
this._card = this._getTemplate();
this._setEventListeners();
this._cardDescription = this._card.querySelector('.card__text');
this._cardLikeCount = this._card.querySelector('.card__like-counter');
this._cardDescription.textContent = this._name;
this._cardImage.src = this._link;
this._cardImage.alt = this._name;
this._cardLikeCount.textContent = this._likes.length;
if (!(this._ownerId === this._userId)) {
this._cardDeleteButton.style.display = 'none';
}
if (this._likes.find((item) => this._userId === item._id)) {
this._cardLikeButton.classList.add('card__like-button_active');
}
return this._card;
}
}
index.js прикладываю
const createCard = (item) => {
const card = new Card(
{
item: item,
handleCardClick: () => {
popupPicture.open(item);
},
handleLikeClick: () => {
card.handleLikeCard();
},
handleDeleteConfirm: () => {
popupDeleteConfirm.setSubmitAction(() => {
popupDeleteConfirm.renderLoadingDelete(true);
api
.delete(item._id)
.then(() => {
card.handleDeleteCard();
popupDeleteConfirm.close();
})
.catch((err) => console.log(err))
.finally(() => popupDeleteConfirm.renderLoadingDelete(false));
});
popupDeleteConfirm.open();
},
},
cardTemplateSelector,
userId,
api
);
const cardElement = card.generateCard();
return cardElement
};
// Экземпляр popup с картинкой
const popupPicture = new PopupWithImage(popupPictureSelector);
popupPicture.setEventListeners();
// Рендер карточек из массива
const cardList = new Section(
{
renderer: (item) => {
cardList.addItem(createCard(item));
},
},
cardsContainerSelector
);
// Экземпляр с данными пользователя
const userInfo = new UserInfo({
name: userNameSelector,
description: userDescriptionSelector,
avatar: userAvatarSelector,
});
const popupProfileEdit = new PopupWithForm(popupProfileSelector, (items) => {
popupProfileEdit.renderLoading(true);
api
.setUserProfile(items)
.then((item) => {
userInfo.setUserInfo(item);
popupProfileEdit.close();
})
.catch((err) => console.log(err))
.finally(() => popupProfileEdit.renderLoading(false));
});
popupProfileEdit.setEventListeners();
popupEditButton.addEventListener('click', () => {
const userData = userInfo.getUserInfo();
nameInput.value = userData.name;
jobInput.value = userData.description;
formValidators['popup-profile'].resetValidation();
popupProfileEdit.open();
});
const popupCardAdd = new PopupWithForm(popupAddCardSelector, (items) => {
popupCardAdd.renderLoading(true);
api
.addUserCard(items)
.then((item) => {
cardList.addItem(createCard(item));
formValidators['popup-add-card'].resetValidation();
popupCardAdd.close();
})
.catch((err) => console.log(err))
.finally(() => popupCardAdd.renderLoading(false));
});
popupCardAdd.setEventListeners();
cardAddButton.addEventListener('click', () => {
formValidators['popup-add-card'].resetValidation();
popupCardAdd.open();
});
const popupAvatarEdit = new PopupWithForm(popupAvatarEditSelector, (items) => {
popupAvatarEdit.renderLoading(true);
api
.editUserAvatar(items)
.then((item) => {
userInfo.setUserAvatar(item);
popupAvatarEdit.close();
})
.catch((err) => console.log(err))
.finally(() => popupAvatarEdit.renderLoading(false));
});
popupAvatarEdit.setEventListeners();
avatarEditButton.addEventListener('click', () => {
formValidators['popup-avatar-edit'].resetValidation();
popupAvatarEdit.open();
});
const popupDeleteConfirm = new PopupWithConfirm(popupDeleteConfirmSelector);
popupDeleteConfirm.setEventListeners();
// Вызовы функций
enableValidation(validatorSelectors);
let userId;
api
.getData()
.then(([cards, userData]) => {
userInfo.setUserInfo(userData);
userId = userData._id;
cardList.renderItems(cards);
})
.catch((err) => console.log(err));