์ฃผ์š” ์ž‘์—…

  • ์˜ต์ €๋ฒ„ ํŒจํ„ด ์ ์šฉ - notify์‹œ ํŽ˜์ด์ง€๋ณ„ ์ปดํฌ๋„ŒํŠธ ๋ฆฌ๋ Œ๋”๋ง
  • MVC ํŒจํ„ด ์žฌ๊ตฌ์กฐํ™”(์‹น ๋œฏ์–ด๊ณ ์นจ)
  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ

ํ•™์Šต ํ‚ค์›Œ๋“œ

  • Jest ํ…Œ์ŠคํŠธ์ฝ”๋“œ
  • javascript class
  • ์˜ต์ €๋ฒ„ ํŒจํ„ด
  • MVC ํŒจํ„ด

https://luxurious-share-af6.notion.site/4-aba822d7763544a5ad64778df911c630?pvs=4

๊ณ ๋ฏผ ๋ฐ ํ•ด๊ฒฐ๊ณผ์ •

TroubleShooting: Class์˜ getter์™€ setter ์„ค์ •

    RangeError: Maximum call stack size exceeded
 
      33 |   }
      34 |   set title(title) {
    > 35 |     this.title = title;
         |               ^
      36 |   }
      37 |   set detail(detail) {
      38 |     this.detail = detail;

getter ํ•จ์ˆ˜์™€ setter ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•จ์— ์žˆ์–ด์„œ ์ž๊พธ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค๋ ค๊ณ  ํ–ˆ์ง€๋งŒ setterํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•จ์œผ๋กœ์จ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.  ๋ฌด์—‡์ด ๋ฌธ์ œ์ธ์ง€ ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด์„œ ์ฐจ๊ทผ์ฐจ๊ทผ ๋ถ„์„ํ•ด๋ณด์•˜๋‹ค.

class Card {
  constructor({
    id,
    author,
    created_at,
    title,
    detail,
    task_column,
    priority,
  }) {
    this.id = id;
    this.author = author;
    this.created_at = created_at;
    this.title = title;
    this.detail = detail;
    this.task_column = task_column;
    this.priority = priority;
  }

Card Class์˜ constructor๋Š” ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๊ณผ์ •์—์„œ this.id = id, author ๋“ฑ์„ ์‹คํ–‰ํ•œ๋‹ค. title๋ฅผ ์˜ˆ๋กœ ๋“ค์–ด๋ณด์ž๋ฉด, this.title = id๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ณผ์ •์ด ์‚ฌ์‹ค์ƒ id์— ํ• ๋‹นํ•˜๋Š” ๊ณผ์ •๊ณผ ๊ฐ™๋‹ค๋Š” ์ ์ด๋‹ค.

  set title(title) {
    this.title = title;
  }

์ด์ „์— ๋‚ด๊ฐ€ ์ผ๋˜ setter ํ•จ์ˆ˜์ด๋‹ค. ๋ณด๋ฉด ์ƒ์„ฑ์ž์—์„œ ํ• ๋‹นํ•˜๋Š” ๊ณผ์ •๊ณผ ๊ฐ™๋‹ค. ๊ทธ๋ ‡๊ธฐ์— this.title = title์ด๋ผ๋Š” ํ• ๋‹น๋ฌธ์€ setterํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ณ , ํ•จ์ˆ˜์—์„œ๋Š” ๋‹ค์‹œ๊ธˆ this.title = title์„ ์‹คํ–‰์‹œํ‚ค๋ฉด setter ํ•จ์ˆ˜๋ฅผ ์žฌ๊ท€์ ์œผ๋กœ ํ˜ธ์ถœํ•˜๋Š” ๊ตฌ์กฐ๊ฐ€ ๋˜์–ด๋ฒ„๋ ธ๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ฐพ์•„๋ณธ ๊ฒฐ๊ณผ ํด๋ž˜์Šค์˜ getter,setterํ•จ์ˆ˜์—์„œ๋Š” ์ฃผ๋กœ property๋ฅผ ๋Œ€์‹œ๋ฐ”(_)๋ฅผ ๋„ฃ์–ด ๊ตฌ๋ถ„ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

get title() {
    return this._title;
  }
set title(title) {
	this._title = title
}

๊ทธ๋ƒฅ ๋‚ด๊ฐ€ ํ•จ์ˆ˜๋•ํ›„๋ผ ํด๋ž˜์Šค๋ฅผ ๋งŽ์ด ์•ˆ ์‚ฌ์šฉํ•ด๋ด์„œ ๋ฉ์ฒญ์ด์Šˆ์˜€๋˜๊ฑธ๋กœ..

์˜ต์ €๋ฒ„ ํŒจํ„ด์˜ ์ ์šฉ ๋ฒ”์œ„

์ฒ˜์Œ์—๋Š” ๊ฐ๊ฐ์˜ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•ด์„œ ๋ฆฌํŒฉํ† ๋ง์„ ํ•œ ๋’ค, ์ปดํฌ๋„ŒํŠธ ๋ณ„๋กœ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฆฌ์•กํŠธ์˜ useState, setState์™€ ๊ฐ™์ด ์œ ํ‹ธํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•ด๋ณผ๊นŒ ํ•˜๋Š” ์ƒ๊ฐ์„ ํ–ˆ์—ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“ค๊ณ  ์žˆ๋Š”, ๋˜ํ•œ ๋‚ด๊ฐ€ ๋งŒ๋“  ํ”„๋กœ์ ํŠธ์˜ ๊ตฌ์กฐ์—์„œ ์˜ต์ €๋ฒ„ ํŒจํ„ด์„ ๊ฐ ์ปดํฌ๋„ŒํŠธ๋งˆ๋‹ค ์ ์šฉํ•˜๋Š” ๊ฒƒ์€ ์•„๋ž˜์™€ ๊ฐ™์€ ์ด์œ ์—์„œ ์˜ค๋ฒ„์—”์ง€๋‹ˆ์–ด๋ง์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง, ์‹œ๋‚˜๋ฆฌ์˜ค์— ๋”ฐ๋ผ ์ง€์†ํ•ด์„œ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๊ณ , ์ด๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ํ‘œํ˜„ํ•ด์•ผ ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ โ€˜์ƒํƒœโ€™๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ํ•ด๋‹น ์ƒํƒœ์˜ ์ •์˜๋กœ ๋‚˜์˜ ํ”„๋กœ์ ํŠธ๋ฅผ ๋ณด์•˜์„ ๋•Œ, ์ •๋ณด ๊ฐฑ์‹ ์ด ์ด๋ฃจ์–ด์งˆ ๋•Œ๋Š” api๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ ์ด์™ธ์˜ ์ƒํ™ฉ์—์„œ๋Š” ๊ฐœ๋ณ„์ ์œผ๋กœ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ํ•  ํ•„์š”๊ฐ€ ์—†์–ด์ง„๋‹ค. ์ด์— ๊ตณ์ด ํ•„์š”ํ• ๊นŒ? ํ•˜๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋‚˜๋Š” ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ํ˜„์žฌ ์‹œ๊ฐ์ ์œผ๋กœ ํ‘œํ˜„๋˜์–ด ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋“ค์„ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ์˜ต์ €๋ฒ„๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉฐ, ์ •๋ณด ๊ฐฑ์‹ ์ด ์ผ์–ด๋‚ฌ์„ ๋•Œ ์˜ต์ €๋ฒ„๋ธ”์—๊ฒŒ notifyํ•  ์ˆ˜ ์žˆ์„๊นŒ? ๋ฅผ ๊ณ ๋ฏผํ–ˆ๋‹ค.

์ปดํฌ๋„ŒํŠธ ๋ณ„๋กœ ๋ฆฌ๋ Œ๋”๋ง์ด ํ•„์š”ํ•œ ๊ณณ์— ์˜ต์ €๋ฒ„๋ธ” ๋‚ด๋ ค์ฃผ๊ธฐ

...
function Main() {
  const observable = new Observable();
  function render() {
    new Header(observable);
    new Mainsection(observable);
    fab.render(observable);
    EventManager.attachEvent("/main");
  }
  return { render };
}
 
export default Main();
 

๋‚˜๋Š” ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„, ํŽ˜์ด์ง€ ๋‹จ์œ„๋กœ ํ•จ์ˆ˜ํ˜•์„ ๋งŒ๋“ค๊ณ , ๋งˆ์น˜ ์ปดํฌ๋„ŒํŠธ์ฒ˜๋Ÿผ ๋ Œ๋”๋งํ•˜๋„๋ก ๋กœ์ง์„ ๊ตฌ์„ฑํ–ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋‚˜๋Š” ์ •๋ณด ๊ฐฑ์‹ ์ด ์ด๋ฃจ์–ด์กŒ์„ ๋•Œ ํ•จ๊ป˜ ๋ Œ๋”๋ง๊ณผ ์ •๋ณด๋ฅผ ๋‹ค์‹œ๊ธˆ fetchํ•ด์˜ฌ ์ˆ˜ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•ด์„œ๋งŒ observable์„ ๊ตฌ๋…ํ•œ ํ›„์—, api ํ˜ธ์ถœ ๋ถ€๋ถ„์—์„œ ๊ธฐ์กด์— ๊ฐ€์กŒ๋˜ ๋ฆฌ๋ Œ๋”๋ง ๋กœ์ง ๋Œ€์‹  ์ฝœ๋ฐฑํ•จ์ˆ˜๋กœ observable์—๊ฒŒ notifyํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด์ฃผ๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ฆฌํŒฉํ† ๋งํ–ˆ๋‹ค.

function Section(observable) {
  observable.subscribe(render);
 
  async function render() {
    try {
      const { data, path } = await fetch();
      console.log("section render:", data);
      const compiledFunction = window.pug.compile(template, {
        basedir: path,
      });
      document.getElementById("sections").innerHTML = "";
      data.forEach((section) => {
        const html = compiledFunction({ section: section }); // ๋ Œ๋”๋ง๋œ HTML
        document.getElementById("sections").innerHTML += html;
        addTodo.render(section.classify);
        if (section.cards)
          card.render(document.getElementById(section.classify), section.cards);
      });
      addcolumn.render();
    } catch (error) {
      alert("์นด๋“œ ์ •๋ณด๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋˜ ์ค‘ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.");
    }
  }
  render();
 
  return {
    render,
  };
}
 
export default Section;
 

์ด์ฒ˜๋Ÿผ ์ •๋ณด ๊ฐฑ์‹ ์ด ์ด๋ฃจ์–ด์ง„ ํ›„์—, fetch๋ฅผ ๋‹ค์‹œ ํ•ด์˜ด์œผ๋กœ์จ ์ •๋ณด๋ฅผ ํ™•์ •์ ์œผ๋กœ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋Š” db์—์„œ ๊ฐ€์ ธ์™€ ๋„์›Œ์ฃผ๋Š” render ํ•จ์ˆ˜๋ฅผ ์˜ต์ €๋ฒ„๋ธ”์— ๊ตฌ๋…ํ•ด์ฃผ๊ณ , ๊ฐฑ์‹ ์ด ์ด๋ฃจ์–ด์กŒ์„ ๋•Œ, ๋ฉ”์ธํŽ˜์ด์ง€์˜ ๊ฒฝ์šฐ ํžˆ์Šคํ† ๋ฆฌ ์ฐฝ ์•ˆ์˜ ๋‚ด์šฉ๋“ค๊ณผ ์นด๋“œ๋“ค์— ๋Œ€ํ•ด์„œ ๋‹ค์‹œ๊ธˆ fetchํ•ด์˜ค๊ณ  ์ •๋ณด๋ฅผ ์ตœ์‹  ์ •๋ณด๋กœ ๋ฆฌ๋ Œ๋”๋ง ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„ํ•˜์˜€๋‹ค.

๋ฆฌ๋ทฐ์š”์ฒญ

์•ˆ๋…•ํ•˜์„ธ์š” ๋ฉ˜ํ† ๋‹˜! ์ €๋Š” ์ˆ˜,๋ชฉ ๋™์•ˆ ์„œ๋ฒ„์˜ ๊ตฌ์กฐ๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•˜๋Š” ์ž‘์—…์„ ์ฃผ๋กœ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ™”์š”์ผ ๋ฉ˜ํ† ๋‹˜์ด ๋ฆฌ๋ทฐํ•ด์ฃผ์‹  ๊ฒƒ์„ ๋ณด๊ณ  ์ œ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ๊ธˆ ๋ณด๋‹ˆ ๊ธฐ์กด์— ๋ชจ๋ธ์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ๋†’์ง€ ์•Š์•„ ํ•œ ๋„๋ฉ”์ธ์— ๋Œ€ํ•œ ๋‹จ์ผ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด๋ผ๊ณ  ์ƒ๊ฐ์„ ํ–ˆ์—ˆ๋˜ ์ ๊ณผ ์ปจํŠธ๋กค๋Ÿฌ์˜ ์—ญํ•  ์ž์ฒด๊ฐ€ ์„œ๋น„์Šค ๋กœ์ง์„ ๋‹ด๊ณ  ์žˆ์—ˆ๋‹ค๋Š” ์ ์ด ๋ฌธ์ œ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด์— ๊ฐœ์„ ํ•œ ์„œ๋ฒ„์˜ ๊ตฌ์กฐ๋ฅผ ๊ฐ„๋‹จํžˆ ๋ง์”€๋“œ๋ฆฌ์ž๋ฉด

  • ์ปจํŠธ๋กค๋Ÿฌ : ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๋Œ€ํ•œ ๋‹จ์ˆœ ์‘๋‹ต/์š”์ฒญ ๊ฐ์ฒด๋ฅผ ํด๋ผ์ด์–ธํŠธ/์„œ๋น„์Šค์— ์ „๋‹ฌ
  • ์„œ๋น„์Šค: ์ผ๋ จ์˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๋“ค์„ ์ „๋ถ€ ์ˆ˜ํ–‰
  • ๋ ˆํฌ์ง€ํ† ๋ฆฌ : db์— ์ง์ ‘์ ์ธ ์ ‘๊ทผ ๋ฐ ์กฐ์ž‘์„ ํ•˜๋Š” ๊ณ„์ธต์œผ๋กœ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด๋ฅผ ๋„˜๊ฒจ๋ฐ›๊ณ  ๋ฐ์ดํ„ฐ ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•จ
  • ๋ชจ๋ธ : ํ•ด๋‹น ๋„๋ฉ”์ธ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ์ฒด๋กœ ๋‹ค๋ฃจ๋ฉฐ, ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ๊ฐ์ฒด๋ฅผ ์„œ๋น„์Šค์—์„œ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋กœ ์ „๋‹ฌํ•˜๋ฉด์„œ ๋ฐ์ดํ„ฐ์˜ ๊ฐฑ์‹ ์„ ๋‹ด๋‹น ์˜ ๊ตฌ์กฐ๋กœ ๊ฐœ์„ ํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๊ฐœ์„ ํ•œ ๊ตฌ์กฐ์— ๋Œ€ํ•ด์„œ ๋ฉ˜ํ† ๋‹˜์˜ ๊ฐ„๋‹จํ•œ ํ”ผ๋“œ๋ฐฑ๊ณผ ์ „์ฒด์ ์ธ ์ฝ”๋“œ์— ๋Œ€ํ•œ ํ”ผ๋“œ๋ฐฑ ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค :) 2์ฃผ์ผ๋™์•ˆ ๊ณ ์ƒํ•˜์…จ์Šต๋‹ˆ๋‹ค!