[TS] Section 9 Dom 요소 선택 및 OOP 렌더링

template tag

<template> 요소 내의 콘텐츠는 페이지가 로드될 때 즉시 렌더링되지 않으며, 따라서 사용자에게는 보이지 않습니다.
하지만 나중에 자바스크립트를 사용하여, 해당 콘텐츠를 보이도록 렌더링할 수 있습니다.

<body>
  <template>
      <h3>모나리자</h3>
      <img src="/examples/images/img_monalisa.png" alt="모나리자">
  </template>
  
  <script>
      function displayTemplate() {
           var frag = document.getElementsByTagName('template')[0];
           var copy = frag.content.cloneNode(true);
           document.body.appendChild(copy);
       }
  </script>
</body>

Autobind" 데코레이터 생성 및 사용하기

bind를 통해 this를 수동으로 바인딩할 수 있지만,
데코레이터를 통해 좀 더 간단하고 유연하게 사용할 수 있다.

// autobind decorator
function autobind(_: any, _2: string, descriptor: PropertyDescriptor) {
  const originalMathod = descriptor.value;

  const adjDescriptor: PropertyDescriptor = {
    configurable: true,
    get() {
      const boundFn = originalMathod.bind(this);
      return boundFn;
    },
  };

  return adjDescriptor;
}

@autobind
private submitHandler(event: Event) {
  event.preventDefault();
  console.log(this.titleInputElement.value);
}

private configure() {
  // bind를 통해 this를 ProjectInput 클래스에 바인드 한다.
  // this.element.addEventListener('submit', this.submitHandler.bind(this));
  // 데코레이터를 이용하면 좀 더 쉽게 this 바인딩을 처리할 수 있다.
  this.element.addEventListener('submit', this.submitHandler);
}

재사용 가능한 검증 기능 생성

수정 전

if (
  enteredTitle.trim().length === 0 ||
  enteredDescription.trim().length === 0 ||
  enteredPeople.trim().length === 0
) {
  alert('Invalid input');
  return;
} else {
  return [enteredTitle, enteredDescription, +enteredPeople];
}

수정 후

// Validation
interface Validatable {
  value: string | number;
  required?: boolean;
  minLength?: number;
  maxLength?: number;
  min?: number;
  max?: number;
}

function validate(validatableInput: Validatable) {
  let isValid = true;
  if (validatableInput.required) {
    isValid = isValid && validatableInput.value.toString().trim().length !== 0;
  }

  if (
    validatableInput.minLength != null &&
    typeof validatableInput.value === 'string'
  ) {
    isValid =
      isValid && validatableInput.value.length >= validatableInput.minLength;
  }
  if (
    // 0일 경우를 고려하여 null 값과 비교
    validatableInput.maxLength != null &&
    typeof validatableInput.value === 'string'
  ) {
    isValid =
      isValid && validatableInput.value.length <= validatableInput.maxLength;
  }
  if (
    validatableInput.min != null &&
    typeof validatableInput.value === 'number'
  ) {
    isValid = isValid && validatableInput.value <= validatableInput.min;
  }
  if (
    validatableInput.max != null &&
    typeof validatableInput.value === 'number'
  ) {
    isValid = isValid && validatableInput.value >= validatableInput.max;
  }
  return isValid;
}
 const titleValidatable: Validatable = {
      value: enteredTitle,
      required: true,
    };

    const descriptionValidatable: Validatable = {
      value: enteredDescription,
      required: true,
      minLength: 5,
    };

    const peopleValidatable: Validatable = {
      value: enteredPeople,
      required: true,
      min: 1,
      max: 5,
    };

    if (
      !validate(titleValidatable) ||
      !validate(descriptionValidatable) ||
      !validate(peopleValidatable)
    ) {
      alert('Invalid input');
      return;
    } else {
      return [enteredTitle, enteredDescription, +enteredPeople];
    }

좋은 웹페이지 즐겨찾기