개발 노트

Javascrip // 15~16일차 게시판, 배열함수(forEach, filter) 본문

Javascript

Javascrip // 15~16일차 게시판, 배열함수(forEach, filter)

Meter216 2022. 11. 18. 19:58

1. 게시판

2. 배열함수

 

 

게시판

 

화면

HTML 페이지가 하나였지만 이젠 다르다 . 페이지를 넘기듯 표시하는건 2가지 방법이 있다.


youtube는 엘리먼트만 갈아 끼우는 것
naver는 아예 페이지를 새로 받아오는것  react view

 

리스트 글쓰기 글수정 글보기 글삭제

 

list.html

 

페이지가 하나라고 하면

--index파일 하나 html끼리 데이터 공유를 하는 방법?

-method : get 데이터 공유는 안되지만... 데이터는 넘긴다.

 

cookie ..

 

브라우저가 만든것

브라우저는 데이터를 저장한다.
데이터저장 = 그냥 글자를 저장한다(파일명) //
document.cookie = "name=이름" 

 

localStorage

window

window.localStorage.setItem('name','ingoo') //전부 스트링으로 변한다 저장하는것
window.localStorage.getItem('name') // 키 값만 입력하면 가져 올 수 있다

JSON.parse // JSON.stringify
객체만드는거 // 스트링으로만드는거

object 안에 있던 내용을 string 으로 바꿔버림
why ? 브라우저가 데이터를 저장하는 방식이 스트링이기 때문

 

cookie와 localStorage 의 차이

 

일단 같은 메커니즘이지만
쿠키가 로컬스토리지가 거의 같지만 저장 용량이 적다. 최대 4kb

웹스토리지
-로컬 스토리지 삭제가 안됨
-세션 스토리지 브라우저를 종료하면 삭제됨

쿠키
통신과 연관이 있음

typeof 타입을 검사하는거 console.log( typeof person)

const person3 = JSON.parse(person2)
console.log(person3)

내가 원하는 데이터를 스트링으로 저장해서 쿠키로 넘긴다음에
쿠키에서 불러 와서 객체로 만든다.

 

게시판 만드는 방법.

 

일단 페이지가 많이 필요하다.

리스트 페이지, 글쓰기 페이지, 글보기 페이지, 글수정 페이지 //

html끼리 데이터를 넘기려면 localStorage를 이용해서 넘겨야한다.

 

localStorage

JS에서 데이터 입력 > 스트링 변환 > localStorge저장 //

localStorage 불러오기 > 객체변환 > 사용 

**지금부터라도 데이터 타입 확인을 잘해야한다. ** console.log(typeof 변수)

 

생성부터 해야한다.

메모리를 생성부터 해야하기에 글쓰기 페이지부터 만들어야한다.

생성자 함수를 만들어서, 객체를 만들고 , 배열을 만들어서 객체에 넣을 수 있도록한다.(배열이 먼저 있긴해야함)

 

**배열을 먼저 로컬스토리지에 넣어놔야 생성을 해서 넣을 때 넣을 수 있다.

--list.js--

let item = localStorage.getItem("boards")
if(item === null){
    const intialState = []
    const state = JSON.stringify(intialState)
    localStorage.setItem("boards", state)
    item = state
}

 

localStorage 가 비어있다면 = Null 값이 뜨게 된다.

그럼 [] 배열을 생성해주고 이 값을 string으로 변환, localStorage에 저장 될 수 있게 해주고,

setItem을 통해 저장해준다 **setItem("저장이름", 변수명) 변수명 = 스트링으로 저장 한 변수.

 

--write.js--

const instance = new Board(subject, content, writer)
// "[]" > []
// boards > []
const boards = JSON.parse(localStorage.getItem("boards"))  //한번에 객체로 만들어서 가져와서 보드에 담기

boards.push(instance)
const item = JSON.stringify(boards) //스트링으로 변환 
localStorage.setItem('boards', item) // boards 라는 이름으로 아이템을 로컬스토리지에 저장

가장 실수가 많이 나는 부분이다.  sumbit 이벤트를 적용시킬 때 생성자 함수를 통해 만든 instance_객체 를 push를 통해 boards에 넣는다.

push까진 instance가 맞지만 JSON.stringify(boards) // 에서 boardsinstance로 하는 실수가 많이 발생한다.

이 경우 위에 있는 boards 를 불러오는 곳에서 저장해둔 배열이 아니라 객체를 불러오게 된다.

결국 boards_객체.push(instance_객체) 가 된다. 

** 객체에 객체를 넣는 것은 없다. 타입 확인 잘하자. 모르겠으면 typeof 찍자.

window.location.href = "/2022.11/2022.11.17/board/view.html?index=" + index

url을 이동시켜 줄 수 있다. submit이벤트함수 안에 넣게 되면 submit 하는 순간 index 값을 달고 view.html로 이동한다.

index를 다는 이유는 이 배열이 몇번째 배열인지 알기 위해서다 

몇번 째 배열인지 알 수 있으면 수정, 삭제가 가능하다. 글을 쓸 때의 JS 이니 index는

const index = boards.length -1 로 부여하면 0부터 시작해서 차례대로 달리게 된다.

 

--list.js--

const tbody = document.querySelector("tbody")
function template(item, index){
    return `
    <tr>
        <td>${item.index}</td>
        <td><a href="/2022.11/2022.11.18/board/view.html?index=${index}">${item.subject}</a></td>
        <td>${item.content}</td>
        <td>${item.date}</td>
        <td>${item.hit}</td>
    </tr>`
}

const boards = JSON.parse(item)
for(let i=0; i<boards.length; i++){
    tbody.innerHTML += template(boards[i], i)
}

createElement가 아니라도 이렇게 엘리먼트를 추가해서 넣을 수 있다.

for의 조건문을  (let i = length-1; i >= 0; 1--) 로 바꾸게 된다면 최신순으로 정렬도 가능하다.

 

--view.js--

const idx = location.search.split("=") // "index=3" ['index','3' 이 된다] 스트링에서 배열
const index = idx[1]  //string
const board = boards[index] //object
const viewfrm = document.querySelectorAll("#viewfrm > div")

for (let i = 0; i < viewfrm.length; i++){
    const id = viewfrm[i].id // element의 id값
    // board.subject = board["subject"] 객체에서 뽑는 법 . , []
    // board[id] - > board["subject"] []안에 변수를 넣어도 작동 
    const span = viewfrm[i].querySelector("span")
    span.innerHTML = board[id]
}

search = url에 있는 값, 물음표 이후의 값을 찾아내주는 메서드이다.

search.split("=") = 을 사이에 둔 값을 나눠 배열로 저장한다. 변수로 받아야한다. 

이렇게 하면 index 값을 받아 올 수 있다.

형변환이 많이 일어나는 곳이니 주의하자.

 

viewfrm은 객체로 불려왔다.

객체에서 값을 뽑는 방법은 2가지가 있었다. 대문자 표기법 board[""] ,  점 표기법 board. 이 있다.

viewfrm[i].id 를 가져와서 변수 선언을 하면 querySelectorAll을 통해서 가져온 div들이 for 문으로 인해 하나씩 선택이 된다.

그 div들의 id 즉 viewfrm[0].divid 를 불러온다. 이 것을 변수 id로 저장해두고

board[id] 를 넣게되면 board에 id값들을 하나씩 불러 올 수 있다.

.표기법은 속성값을 찾으려 하기 때문에 안된다.

하면서 가장 생각이 안돌아갔던 부분이다

 

--view.js--

function debtnclickHandler(e){
    if (confirm("삭제 하시겠습니까?") == true){
        alert("삭제되었습니다.")
        boards.splice(index, 1)
        const item = JSON.stringify(boards)
        localStorage.setItem("boards", item)
        location.href = "../board/list.html"
    }
}

debtn.addEventListener("click", debtnclickHandler)

삭제 버튼 

 

--update.js--

 

기본적으로 불러오는 방식이 view와 비슷하다. 

url에서 index 값을 추출해 오고 추출한 값으로 몇번째 배열의 값들인지 알 수 있다.

subject.value = boards[index].subject
writer.value = boards[index].writer
content.innerHTML = boards[index].content // 이건 textarea 기 때문에 value 값이 아니라 innerHTML이다 
//내용을 채우는건 inner 내용을 보는건 value

frm.addEventListener("submit", function(e){
    e.preventDefault()
    console.log(subject)

    boards[index].subject = subject.value
    boards[index].writer = writer.value
    boards[index].content = content.value
    const data = JSON.stringify(boards)
    localStorage.setItem("boards", data)

    location.href = `/2022.11/2022.11.18/board/view.html?index=${index}`
})

contetn에서 엘리먼트를 textarea로 설정해놓았다면 처음 불러올 때 value 값이 아니라 innerHTML으로 설정해야한다.

근데 넣을 땐 또 value다 .. 정상이 아닌놈이다.

 

textarea로 불러온것이 아니라면.

function rebtnclickHandler(e){
    for (let i = 0; i < viewfrm.length; i++){
        const id = viewfrm[i].id 
        const input = viewfrm[i].querySelector("input")
        board[id] = input.value
    }
    // console.log(board)
    
    boards[index] = board
    const item = JSON.stringify(boards)
    localStorage.setItem("boards", item)

    window.location.href = "/2022.11/2022.11.17/board/view.html?index=" + index
}

input을 만들어 넣는것으로도 간단히 설정이 가능하긴하다. 근데 정상적으론 textarea를 넣는것이 맞는 것 같다.

 

삭제, 수정 버튼 만들어서 form에 넣는 실수가 없길.


배열함수

forEach

const arr= [2,7,5,4,1]
arr.forEach(function(value, index){
	console.log(value,index)
})

2,0 7,1 5,2 4,3 1,4 가 찍힌다

내부적으로 for 함수가 찍힌다고 생각하면 좀 쉽나 ?

for을 생략하고 싶어서 만든 함수 같은 느낌이다.

 

단점은 반복을 멈출 수가 없다. 폭주기관차같은 느낌, return도 먹히지 않는다.

if (index === 3) return 을 써도 콜백함수만 리턴을 시킨다.

3을 빼고 계속 돈다. 뭔가 3을 찍는것만 리턴시키는 느낌 ?

지가 배열을 끝낼 때 까지 계속 도는 함수.

 

Filter

**Array.prototype.filter()**

const arr = [2,7,5,4,5]
const arr2 = arr.filter((v) => v===5)   새로운 값을 변환해주는거 arr는 손상되지 않는다
console.log(arr2)

내가 지정한 값을 뽑아주는 함수. 다만 뽑아내기만 할 뿐 따로 지정을 해주지 않기 때문에 변수로 빼줘야한다.