반응형

story.js
-image.likeState에 따라 이미지태그의 active 가 보일지를 정해야한다. 

function getStoryItem(image) {
    let item =
    `<div class="story-list__item">
  ...
 <button>`;
      if(image.likeState){
        item += `<i class="fas fa-heart active" id="storyLikeIcon-${image.id}" onclick="toggleLike(${image.id})"></i>`;

      }else{
        item += `<i class="far fa-heart" id="storyLikeIcon-${image.id}" onclick="toggleLike(${image.id})"></i>`;

      }

 item += `
 </button>
 
 <span class="like"><b id="storyLikeCount-${image.id}">${image.likeCount} </b>likes</span>


...

    return item

}

 

그 정보는 storyLoad()함수에서 '/api/image' api에 응답하여 done을 통해 image를 가져올때 담아가야한다. 

function storyLoad() {
    $.ajax({
        url:`/api/image`,
        ataType : "json"
    }).done(res=>{
        console.log(res);
        res.data.forEach((image) => {
            let storyItem = getStoryItem(image)
            $("#storyList").append(storyItem);

        })
    }).fail(error => {
        console.log("오류", error);

    });
}

storyLoad();

 

Image.class
- Image를 가져올때 like정보를 가져오려면 Like과의 연관관계가 필요하다. 
- OneToMany 는 lazy 로딩이 기본이므로 likes의 getter를 호출하면 이미지의 like정보를 가져올 수 있다. 
- boolean타입으로 likeState 만들어준다. 이때 @Transient 어노테이션으로 db에 컬럼생성 막아준다. 
- 또한 좋아요 수 를 구하는 likeCount를  @Transient 어노테이션으로 만들어 준다. 

@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class Image {

    ...

    //이미지 좋아요 정보
    @JsonIgnoreProperties({"image"})
    @OneToMany(mappedBy = "image") //lazy가 기본
    private List<Likes>likes;
    
   @Transient //DB에 컬럼이 만들어지지 않는다.
    private boolean likeState;

    @Transient
    private int likeCount;
   ...
    }

ImageService.class
 
예컨데 '2'로 로그인 한다고 하자
-> 2가 팔로우한 계정의 이미지롤 for문으로 모두 가져오기
-> 각 이미지의 좋아요 정보를 모두 가져와서
-> 그 좋아요가 내가 좋아요 한지 판별하기(image의 like정보의 user와 principalId가 같은지 보기)
    해당 이미지에 좋아요한 사람들을 찾아서 현재 로긴한 사람이 좋아요 한것인지 비교
-> 만약에 같다면 likeState에 true값 넣기

- 또한 setLikeCount 로 좋아요 수를 images에 넣어준다.

@RequiredArgsConstructor
@Service
public class ImageService {

    private final ImageRepository imageRepository;

    @Transactional(readOnly = true)
    public List<Image>imageStory(int principalId){
        List<Image> images = imageRepository.mStory(principalId);
     
        images.forEach((image)->{

            image.setLikeCount(image.getLikes().size());

            image.getLikes().forEach((like) -> {
                if(like.getUser().getId() == principalId){ 
                    image.setLikeState(true);
                }
            });
        });

       return images;
    }
   ...
    }
}

  

story.js

// (3) 좋아요, 안좋아요
function toggleLike(imageId) {
   let likeIcon = $(`#storyLikeIcon-${imageId}`);

   if (likeIcon.hasClass("far")) { //빈하트-> LIKE하겠다

       $.ajax({
                 type: "post",
                 url: `/api/image/${imageId}/likes`,
                 dataType: "json"
              }).done(res=>{
				//b태그 내용의 text부분을 가져온다
                 let likeCountStr = $(`#storyLikeCount-${imageId}`).text(); 
                 let likeCount = Number(likeCountStr) + 1;
                 $(`#storyLikeCount-${imageId}`).text(likeCount);

                 likeIcon.addClass("fas");
                 likeIcon.addClass("active");
                 likeIcon.removeClass("far");
              }).fail(error=>{
                 console.log("오류", error);
              });

   } else {  //빨간하트 ->UNLIKE 하겠다.

        $.ajax({
                 type: "delete",
                 url: `/api/image/${imageId}/likes`,
                 dataType: "json"
              }).done(res=>{

                 let likeCountStr = $(`#storyLikeCount-${imageId}`).text();
                 let likeCount = Number(likeCountStr) - 1;
                 $(`#storyLikeCount-${imageId}`).text(likeCount);

                 likeIcon.removeClass("fas");
                 likeIcon.removeClass("active");
                 likeIcon.addClass("far");
              }).fail(error=>{
                 console.log("오류", error);
              });

   }
}

+ Recent posts