프로젝트는 끝났지만 기능 구현에 대한 도전은 끝나지 않았다2
<게시글 목록에서 별점 띄우기>
- 현재 상황
- 각 게시글마다 별점은 붙어 있지만 색칠은 1번째 게시글에만 되는 상황
- 각 페이지별로 별점이 다르게 색칠되어 있지만 해당 게시글의 별점과 무관하게 색칠됨
// loader.js
// 게시글 목록 UI
function postList(posts, post_list) {
posts.forEach(post => {
const newCol = document.createElement("div");
newCol.setAttribute("class", "col")
newCol.setAttribute("onclick", `postDetail(${post.pk})`)
const newCard = document.createElement("div")
newCard.setAttribute("class", "card h-100")
newCard.setAttribute("id", post.pk)
newCol.appendChild(newCard)
const postImage = document.createElement("img")
postImage.setAttribute("class", "card-img-top")
if (post.image) {
postImage.setAttribute("src", `${backend_base_url}${post.image}`)
} else {
postImage.setAttribute("src", "https://cdn11.bigcommerce.com/s-1812kprzl2/images/stencil/original/products/426/5082/no-image__12882.1665668288.jpg?c=2")
}
newCard.appendChild(postImage)
const newCardBody = document.createElement("div")
newCardBody.setAttribute("class", "card-body")
newCard.appendChild(newCardBody)
const newCardTile = document.createElement("h5")
newCardTile.setAttribute("class", "card-title")
newCardTile.innerText = post.title
newCardBody.appendChild(newCardTile)
post_list.appendChild(newCol)
const newCardStar = document.createElement("div")
newCardStar.setAttribute("class", "rating")
newCardStar.setAttribute("id", "star")
newCard.appendChild(newCardStar)
const newCardinputStar1 = document.createElement("input")
newCardinputStar1.setAttribute("class", "rate_radio")
newCardinputStar1.setAttribute("type", "checkbox")
newCardinputStar1.setAttribute("value", "1")
newCardinputStar1.setAttribute("id", "rating1")
newCardinputStar1.setAttribute("disabled", "")
newCardStar.appendChild(newCardinputStar1)
const newCardlabel1 = document.createElement("label")
newCardlabel1.setAttribute("for", "rating1")
newCardStar.appendChild(newCardlabel1)
const newCardinputStar2 = document.createElement("input")
newCardinputStar2.setAttribute("class", "rate_radio")
newCardinputStar2.setAttribute("type", "checkbox")
newCardinputStar2.setAttribute("value", "2")
newCardinputStar2.setAttribute("id", "rating2")
newCardinputStar2.setAttribute("disabled", "")
newCardStar.appendChild(newCardinputStar2)
const newCardlabel2 = document.createElement("label")
newCardlabel2.setAttribute("for", "rating2")
newCardStar.appendChild(newCardlabel2)
const newCardinputStar3 = document.createElement("input")
newCardinputStar3.setAttribute("class", "rate_radio")
newCardinputStar3.setAttribute("type", "checkbox")
newCardinputStar3.setAttribute("value", "3")
newCardinputStar3.setAttribute("id", "rating3")
newCardinputStar3.setAttribute("disabled", "")
newCardStar.appendChild(newCardinputStar3)
const newCardlabel3 = document.createElement("label")
newCardlabel3.setAttribute("for", "rating3")
newCardStar.appendChild(newCardlabel3)
const newCardinputStar4 = document.createElement("input")
newCardinputStar4.setAttribute("class", "rate_radio")
newCardinputStar4.setAttribute("type", "checkbox")
newCardinputStar4.setAttribute("value", "4")
newCardinputStar4.setAttribute("id", "rating4")
newCardinputStar4.setAttribute("disabled", "")
newCardStar.appendChild(newCardinputStar4)
const newCardlabel4 = document.createElement("label")
newCardlabel4.setAttribute("for", "rating4")
newCardStar.appendChild(newCardlabel4)
const newCardinputStar5 = document.createElement("input")
newCardinputStar5.setAttribute("class", "rate_radio")
newCardinputStar5.setAttribute("type", "checkbox")
newCardinputStar5.setAttribute("value", "5")
newCardinputStar5.setAttribute("id", "rating5")
newCardinputStar5.setAttribute("disabled", "")
newCardStar.appendChild(newCardinputStar5)
const newCardlabel5 = document.createElement("label")
newCardlabel5.setAttribute("for", "rating5")
newCardStar.appendChild(newCardlabel5)
//원래 별 띄우기
for (let i = 1; i <= post.star; i++) {
document.getElementById(`rating${i}`).checked = true
console.log(`rating${i}`)
}
});
}
- 현재 코드 상황,,,
- 팀원들과 고민을 하다가 결국 튜터님께 질문을 하러 갔다
- 문제를 찾았다
- 지금 별의id 값을 가져와서 true로 바꿔주고 있는데 id값은 고유해야 하는데 각 게시글마다 rating1 ~ rating5로 id값이 매겨져 있다
- 그리고 튜터님이 저렇게 반복되는 코드는 for문에 넣어주라고 하셔서 일단 생성되는 빈 별들을 for문에 넣기로 했다
- 별점을 찾아서
첫 번째 시도 - 별 모양 생성 부분 for문으로 감싸기
// loader.js
// 게시글 목록 UI
function postList(posts, post_list) {
posts.forEach(post => {
...
for (let i = 1; i <= 5; i++) {
`const newCardinputStar${i} = document.createElement("input")
newCardinputStar${i}.setAttribute("class", "rate_radio")
newCardinputStar${i}.setAttribute("type", "checkbox")
newCardinputStar${i}.setAttribute("value", ${i})
newCardinputStar${i}.setAttribute("id", "rating${i}-${post.pk}")
newCardinputStar${i}.setAttribute("disabled", "")
newCardStar.appendChild(newCardinputStar${i})
const newCardlabel${i} = document.createElement("label")
newCardlabel${i}.setAttribute("for", "rating${i}")
newCardStar.appendChild(newCardlabel${i})`
}
...
- 일단 1부터 5까지 반복되니까 for문을 넣어서 코드를 줄였다
- id를 고유하게 하기 위해 rating1-12, rating2-12 이런식으로 id값이 들어가게끔 했다
- 처음엔 for문을 겹쳐서 2번 돌려야 하나....1~5 한 번 posts 개수만큼 또 한 번..
- 이렇게 생각을 했었는데 post.pk를 쓰면 for문을 또 돌릴 필요가 없어진다
- 그리고 posts 개수를 id에 넣으면 다른 페이지에서 같은 아이디 값을 가진 별점 태그가 생기게 돼서 뭔가 문제가 있을 것 같다 고유한 숫자인 pk를 넣는 건 맞는 선택 같다!
- 그리고 숫자가 있는 부분에 다 i를 넣어야 한다고 생각해서 코드 전체를 백틱으로 감쌌다
- 이렇게 하고 실행해보니 당연히 안 됐다 ㅋ
- 별점은 물론 게시글 리스트까지 싹 사라져서 상심이 컸다
두 번째 시도
// load.js
...
for (let i = 1; i <= 5; i++) {
const newCardinputStar`${i}` = document.createElement("input")
newCardinputStar`${i}`.setAttribute("class", "rate_radio")
newCardinputStar`${i}`.setAttribute("type", "checkbox")
newCardinputStar`${i}`.setAttribute("value", `${i}`)
newCardinputStar`${i}`.setAttribute("id", `rating${i}-${post.pk}`)
newCardinputStar`${i}`.setAttribute("disabled", "")
newCardStar.appendChild(newCardinputStar$`{i}`)
const newCardlabel`${i}` = document.createElement("label")
newCardlabel`${i}`.setAttribute("for", "rating${i}")
newCardStar.appendChild(newCardlabel`${i}`)
}
...
- 전체 백틱을 씌우니 문자열로 인식해서 메서드가 제대로 동작하지 않는 거라는 판단을 했다
- 그래서 이렇게 백틱을 i가 필요하다고 생각되는 부분만 감싸는 걸로 바꿨다
- 그랬더니 const 선언하는 부분에서 밑줄이 떴다
- 장렬히 실패....
세 번째 시도 - 성공!
// loader.js
...
for (let i = 1; i <= 5; i++) {
const newCardinputStar = document.createElement("input")
newCardinputStar.setAttribute("class", "rate_radio")
newCardinputStar.setAttribute("type", "checkbox")
newCardinputStar.setAttribute("value", `${i}`)
newCardinputStar.setAttribute("id", `rating${i}-${post.pk}`)
newCardinputStar.setAttribute("disabled", "")
newCardStar.appendChild(newCardinputStar)
const newCardlabel = document.createElement("label")
newCardlabel.setAttribute("for", `rating${i}`)
newCardStar.appendChild(newCardlabel)
}
//원래 별 띄우기
for (let j = 1; j <= post.star; j++) {
document.getElementById(`rating${j}-${post.pk}`).checked = true
}
...
- 변수명에 i 붙이는 걸 뺐더니 드디어 됐다...!!
- for문을 겹쳐서 도는 게 아니라 별 띄우는 부분도 i로 해도 문제없이 출력되지만 뭔가 그냥 보기에 다른 게 좋지 않을까 싶어서 j로 했다