@paravozuk

JavaScript and API. Как безболезненно перекинуть запросы и обработку из компонента карточки в index.js?

Добрый день. Столкнулся с проблемой, которая никак не поддается моему решению.
Во время написания достаточно легкой страницы я запихнул в класс карточки запросы к 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));
  • Вопрос задан
  • 357 просмотров
Пригласить эксперта
Ответы на вопрос 1
@zkrvndm
Софт для автоматизации
Если речь идет об AJAX запросах, то просто наложи манкипатч на XMLHttpRequest или fetch.
В манкипатче уже проверяешь запрос и делаешь переадресацию на правильный адрес, по условию.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы