타입스크립트 Section 9 : DOM 요소 선택 및 OOP 렌더링

BRANDY·2023년 3월 18일
0

this.hostElement는 템플릿 내용을 렌더링 하려는 엘리먼트에 대한 참조를 보유하는 것.
this.templateElement는 이 내용을 보유하는 템플릿에 대한 접근성을 제공한다.

this.templateElement = document.getElementById('project-input')

으로 접근할 수 있다.

오류가 발생하는데 이를 해결하기 위해

templateElement: HTMLTemplateElement;

를 클래스에 직접 추가한다. 저장될 타입은 HTMLTemplateElement로 명확히 한다. 이 타입은 전역에서 사용할 수 있다. lib에 dom을 추가하였기 때문.

타입스크립트는 html파일을 분석하지 않기 때문에 값이 null이 될 수 있다는 오류가 발생. 느낌표를 추가하여 null값이 들어오지 않을거라고 타입스크립트에게 알려줄 수 있다

this.templateElement = document.getElementById('project-input')!;

혹은 변수를 생성하여 조건문을 작성하고 null이 아니라면 의 내요을 작성해준다.

혹은 타입 캐스팅을 활용하여

this.templateElement = <HTMLTemplateElement>document.getElementById('project-input')!;

를 작성하여 해결한다.

혹은

  this.templateElement = document.getElementById('project-input')! as HTMLTemplateElement;

로 해결한다.

이러한 방법들로 여기에 가져오는 것이 null아니고 특정한 타입이 될 것이라고 말해줄 수 있다.

hostElement도 작성해주어야 하는데 index.html의

를 렌더링 해야한다.

그러므로 클래스에

hostElement: HTMLDivElement;

를 작성해준다.

같은 식으로 작성하면

this.hostElement = document.getElementById('app');

이전과 똑같은 문제인 null 값이 될 수 있다는 오류가 발생
!와 as로 해결해준다.

this.hostElement = document.getElementById('app')! as HTMLDivElement; 

이제 이 엘리먼트들에 접근할 수 있지만 아무것도 렌더링 할 수 없다. 이를 위해 templateElement의 내용을 가져와야 한다
템플릿 태그 안에 있는것을 가져와서 이것을 dom에 렌더링한다.

constructor에

const importedNode = document.importNode();

를 작성하는데 이 메서드는 전역 문서 객체에 제공되는 메서드이다.

constructor에

const importedNode = document.importNode(this.templateElement.content);

인자에는 내용을 전달해야 하기 때문에 .content를 명확히 전달하자. 두번째 인자에는 깊은복사를 통해 가져올 것인지 nest 수준으로 가져올 것인지 정한다. 깊은복사로 작성(true)

constructor에

const importedNode = document.importNode(this.templateElement.content, true);

importedNode의 타입은 타입스크립트가 추론하였다. 이제 이것을 이용해서 콘텐츠를 렌더링할 수 있다.

이를 위해 새로운 메서드를 입력한다.

private attach() {
this.hostElement.insertAdjacentElement('afterbegin');
   }
 }

이것은 HTMLElement를 삽입하기 위해 자바스크립트 브라우저에서 제공하는 기본 메서드이다.

afterbegin을 작성하여 여는 태그가 바로 시작되는 곳에 삽입
두번쨰 인자는 importedNode를 전달할건데, 이는 생성자에서만 사용할 수 있고 이것은 DocumentFragment라서 바로 삽입할 수 없다.
index.html 내용을 확인하여 이것이 form 내용이라는것을 확인 후
클래스에

element: HTMLFormElement; 

를 추가하고
constructor에

this.element = importedNode.firstElementChild as HTMLFormElement; 

라고 타입스크립트에 말해주고

private attach() {
this.hostElement.insertAdjacentElement('afterbegin', this.element);
  }
 }

두번째 인자로
this.element를 전달해주면 우리가 삽입하려는 노드를 가르키는 확실한 프로퍼티가 될 수 있다.

그 후 생성자에 attach 메서드도 호출하여 코드가 실행되도록 해야한다.

this.attach();

이제 모든 형식을 갖추었고 새로운 상수를 간단히 생성해보면

const prjInput = new ProjectInput();

컴파일 후 프라우저로 돌아가면 프로젝트 양식이 출력되어있다.

최종 코드

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);
  }
}

const prjInput = new ProjectInput();
profile
프런트엔드 개발자

0개의 댓글