Project Drag & Drop 1๏ธโฃ
! & as
TypeScript์์ DOM ์กฐ์ํ ๋ ์ค๋ฅ ํด๊ฒฐํ๊ธฐ
class ProjectInput {
templateElement: HTMLTemplateElement;
hostElement: HTMLDivElement;
constructor() {
this.templateElement = document.getElementById(
'project-input'
)! as HTMLTemplateElement;
this.hostElement = document.getElementById('app')! as HTMLDivElement;
}
}
document.getElementById('id');
์์ !
๋ฅผ ์ถ๊ฐํ๋ ์ด์ ๋ TypeScript๊ฐ ์ด๊ฒ์ด null
์ผ์๋ ์๋ค๊ณ ์ถ๋ก ํ๊ธฐ ๋๋ฌธ์ด๋ค.
!
๋ฅผ ๋ถ์ฌ์ฃผ๋ฉด null
์ด ์๋๋ผ๋ ๊ฒ์ ์๋ ค์ฃผ๊ฒ ๋๋ค.
document.getElementById('id')!;
๋ก null
์ด ์๋๋ผ๋ ๊ฒ๊น์ง ์๋ ค์ฃผ์๋๋ฐ๋ ์ค๋ฅ๊ฐ ๋จ๋๋ฐ,
getElementById
๋ id
์ ๋ณด๋ก HTML ์์๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ TypeScript๋ ๊ฐ์ ธ์จ ์์๊ฐ div
์ธ์ง a
์ธ์ง li
์ธ์ง ๋ฑ๋ฑ.. ๋ชจ๋ฅธ๋ค!
ํด๋น ์์๊ฐ ์ด๋ค ์์๋ผ๊ณ ์๋ ค์ฃผ๊ธฐ ์ํด์ type casting์ ํด์ฃผ๋ ๊ฒ์ด document.getElementById('id')! as HTMLDivElement;
์ด๋ค.
์ฐธ๊ณ ๋ก ์ด ์ฝ๋๋ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ์ธ ์ ์๋ค.
const div = document.getElementById('im-div')! as HTMLDivElement;
const div = <HTMLDivElement>document.getElementById('im-div');
importNode
importNode()
๋ ๋
ธ๋๋ฅผ ๋ณต์ฌํ๋ ๋ฉ์๋์ด๋ค.
const node = document.importNode(externalNode, deep);
2๊ฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ํ์๋กํ๋๋ฐ,
externalNode
๋ ๋ค๋ฅธ ๋ฌธ์์์ ๊ฐ์ ธ์ฌ ๋
ธ๋์ด๊ณ
deep
์ boolean
ํ์
์ผ๋ก externalNode
์ ์์ ์์๋ค์ ํฌํจํ์ฌ ๋ณต์ฌํ ๊ฒ์ธ์ง ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ๋ค.
class ProjectInput {
templateElement: HTMLTemplateElement;
hostElement: HTMLDivElement;
constructor() {
this.templateElement = document.getElementById(
'project-input'
)! as HTMLTemplateElement;
this.hostElement = document.getElementById('app')! as HTMLDivElement;
const importedNode = document.importNode(
this.templateElement.content,
true
);
}
}
importedNode
๋ templateElement.content
(template ํ๊ทธ ์ฌ์ด์ HTML ์ฝ๋)๋ฅผ ๊ฐ์ ธ์ค๋ฉด์ ๊ทธ ์์ ์์๋ค์ ๋ด์ฉ์ ์ ๋ถ ์ทจํ๊ณ ์ ํ๋ ์ฝ๋์ด๋ค.
์ฐธ๊ณ ๋ก, importedNode
์ ๋ง์ฐ์ค๋ฅผ ์ฌ๋ ค๋ณด๋ฉด TypeScript๊ฐ ์ค์ค๋ก ํ์
์ DocumentFragment
๋ก ์ถ๋ก ํ๋ค.
DocumentFragment
๋ DOM๊ณผ ๋ณ๊ฐ๋ก ๋ฉ๋ชจ๋ฆฌ์์๋ง ๋ฐ๋ก ์กด์ฌํ๋ ๊ป๋ฐ๊ธฐ ๊ฐ์ ์กด์ฌ๋ค.
DOM ํธ๋ฆฌ์ ์ง์ ์กด์ฌํ๋ ๊ฒ์ด ์๋๊ธฐ ๋๋ฌธ์ ์ ๊ทผ ์๋๊ฐ ๋น ๋ฅด๋ฉฐ ์ฑ๋ฅ ์ต์ ํ์ ์ข๋ค.
React์์๋ ์ต์์ ๋ ธ๋๋ฅผ ๊ฐ์ธ์ผํ๋ ์ํฉ์ด ์๊ธธ ๋<Fragment></Fragment>
๋ฅผ ์ฐ๋ฉด ์ข๋ค๊ณ ํ๋ค..!
insertAdjacentElement()
insertAdjacentElement()
๋ ํน์ ์์น์ ์์๋ฅผ ์ฝ์
ํ๋ ๋ฉ์๋์ด๋ค.
targetElement.insertAdjacentElement(position, element);
2๊ฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ํ์๋ก ํ๊ณ ๊ฐ ๋ด์ฉ์ ๋ค์๊ณผ ๊ฐ๋ค.
position
์ targetElement
์ ์์น๋ฅผ ๊ธฐ์ค์ผ๋ก ์ด๋์ ์์๋ฅผ ์ฝ์
ํ ๊ฒ์ธ์ง๋ฅผ ์ ํ๋ค.
'beforebegin'
:targetElement
์์ ์ฝ์ ํ๋ค.'afterbegin'
:targetElement
๋ด๋ถ์ ์ฒซ๋ฒ์งธ ์์ ์์ ์ฝ์ ํ๋ค. (targetElement
์ ์ฒซ๋ฒ์งธ ์์์ด ๋๋ ๊ฒ)'beforeend'
:targetElement
๋ด๋ถ์ ๋ง์ง๋ง ์์ ๋ค์ ์ฝ์ ํ๋ค. (targetElement
์ ๋ง์ง๋ง ์์์ด ๋๋ ๊ฒ)'afterend'
:targetElement
๋ค์ ์ฝ์ ํ๋ค.
position
์string
์ผ๋ก ์์ฑํด์ฃผ์ด์ผ ํจ!'beforebegin'
,'afterbegin'
,'beforeend'
,'afterend'
element
๋ ์ฝ์
ํ๊ณ ์ ํ๋ ์์๋ฅผ ์๋ฏธํ๋ค.
class ProjectInput {
templateElement: HTMLTemplateElement;
hostElement: HTMLDivElement;
element: HTMLFormElement;
constructor() {
this.templateElement = document.getElementById(
'project-input'
)! as HTMLTemplateElement;
this.hostElement = document.getElementById('app')! as HTMLDivElement;
const importedNode = document.importNode(
this.templateElement.content,
true
);
this.element = importedNode.firstElementChild as HTMLFormElement;
this.attach();
}
private attach() {
this.hostElement.insertAdjacentElement('afterbegin', this.element);
}
}
element
๋ importedNode
์ ์์ ์ค ์ฒซ๋ฒ์งธ์ธ form
์์์ด๋ค.
attach()
๋ฉ์๋๋ hostElement
์์ element
๋ฅผ ์ฝ์
ํ๋ ๋ฉ์๋์ด๋ค.
์ฌ๊ธฐ๊น์ง ์ฝ๋๋ฅผ ์์ฑํ ๋ค ์ธ์คํด์ค๋ฅผ ์์ฑํ ํ๋ฉด
app.ts
๊ฐ ์์ฑ๋์ง ์์ ์ํ์์npm start
๋ฅผ ์คํํ๋ฉด ๋น ํ๋ฉด๋ง ๋์ค๋๋ฐ,
html ์์๋ค์ดtemplate
ํ๊ทธ ์์ ์จ์ด์๊ธฐ ๋๋ฌธ์ด๋ค.template
๋ ํ์ด์ง๋ฅผ ๋ถ๋ฌ์จ ์๊ฐ ์ฆ์ ๊ทธ๋ ค์ง์ง๋ ์์ง๋ง DOM ์กฐ์์ ํตํด ํ๋ฉด์ ๋ถ๋ฌ์ฌ ์ ์๋ค.
Binding error
private submitHandler(event: Event) {
event.preventDefault();
console.log(this.titleInputElement.value);
}
private configure() {
this.element.addEventListener('submit', this.submitHandler);
}
element
์ form
์ด ์ ์ถ๋๋ฉด submitHandler
๊ฐ ์๋ํ๋๋ก ์ฝ๋๋ฅผ ์์ฑํ๋ค.
Title์ ๋ด์ฉ์ ์์ฑํ๊ณ ์ ์ถํด๋ณด๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
์ฝ๋๋ฅผ ๋ณด๋ฉด configure()
์์ submitHandler()
๋ฉ์๋๋ฅผ ์ด๋ฒคํธ ๋ฆฌ์ค๋์ ๋ฐ์ธ๋ฉํด๋์๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์๋๋๋ submitHandler()
๋ this
๋ฅผ ๋ค์ ์ด๋ฒคํธ ๋์์ผ๋ก ๋ฐ์ธ๋ฉํ๋ค.
์ฝ๋๊ฐ ์คํ๋๋ ์์ ์ this
๊ฐ class
๋ฅผ ๊ฐ๋ฆฌํค์ง ์๊ธฐ ๋๋ฌธ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
๊ฐ๋จํ ํด๊ฒฐ๋ฐฉ๋ฒ์ submitHandler()
๊ฐ ๋ฐ์ธ๋ฉํ ๋์์ ์ง์ ํด์ฃผ๋ ๊ฒ์ด๋ค.
private configure() {
this.element.addEventListener('submit', this.submitHandler.bind(this));
}
์ด ๊ฒฝ์ฐ ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ์ฐธ์กฐํ๋ this
์ submitHandler()
๊ฐ ์ฐธ์กฐํ๋ this
๊ฐ ๋์ผํด์ง๋ค.
๋ค๋ง ์ด ๋ฐฉ๋ฒ์ ๋ค๋ฅธ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ๋ง๋ค์ด ์ฃผ์์ ๋ ๋งค๋ฒ ๋ฐ์ธ๋ฉ์ ๋ฐ๋ก ์ง์ ํด์ฃผ์ด์ผ ํ๊ธฐ ๋๋ฌธ์,
๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ํตํด ์๋์ผ๋ก ๋ฐ์ธ๋ฉ๋๋๋ก ํ๋ ๊ฒ๋ ๋ ํ๋์ ๋ฐฉ๋ฒ์ด๋ค.
https://monshou.tistory.com/118#article-1-2--autobind-decorator
[TS] Decorators 2๏ธโฃ
Decorators 2๏ธโฃ Decorator the synthetic sugar ํด๋์ค ๋ฐ์ฝ๋ ์ดํฐ๋ constructor๋ฅผ ๋ฐํํ๋ฉด์ ๊ธฐ์กด constructor๋ฅผ ํ์ฅํ ์ ์๋ค. constructor๋ฅผ ํ์ฅํ ๋ super();๋ ๊ธฐ์กด ํด๋์ค ํ์ฅ์์์ ๋ง์ฐฌ๊ฐ์ง๋ก ๊ธฐ์กด ํด๋
monshou.tistory.com
autobind
๋ฐ์ฝ๋ ์ดํฐ ์ ์ฉํ ๋ค์ ํ๋ฉด
'๐ Study > TypeScript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[TS] Drag & Drop 3๏ธโฃ (3) | 2023.03.31 |
---|---|
[TS] Drag & Drop 2๏ธโฃ (3) | 2023.03.30 |
[TS] Decorators 3๏ธโฃ (0) | 2023.03.24 |
[TS] Decorators 2๏ธโฃ (0) | 2023.03.22 |
[TS] Decorators 1๏ธโฃ (1) | 2023.03.20 |