공부하는 블로그

리액트와 뷰로 같은 앱을 만들어 보았다.(Part 2: Angular) 본문

자바스크립트

리액트와 뷰로 같은 앱을 만들어 보았다.(Part 2: Angular)

devtimothy 2018. 9. 14. 14:05

리액트와 뷰로 같은 앱을 만들어 보았다.(Part 2: Angular)

리액트와 뷰로 같은 앱을 만들었는데, Angular가 안 낄수 없죠!

Part 1을 아직 읽지 않았습니까? 여기에서 확인하세요.

저는 Angular를 매일 직장에서 사용하지만, 자바스크립트 세계에서는 다른 모든 프레임 워크에 대한 정보는 얻을 수 없었습니다. 나는 같은 사과라도 이것저것 비교하는 것을 좋아합니다! 그래서 React vs Vue에 대한 Sunil Sandhu의 글에 숟가락을 얹게 되었습니다. 자, 여기 React vs Vue vs Angular의 비교입니다!

앱의 외형은 어떨까요?

[Player 3 이 게임에 입장하였습니다]

Part 1과 마찬가지로 css는 다른 두 프레임워크의 위치와 거의 비슷합니다.

이 Angular 애플리케이션은 Angular CLI (명령 줄 인터페이스)에 의해 생성됩니다. Angular는 종종 'ng'로 단축되기 때문에 이 앱을 만드는 명령은 ng generate ng-todo입니다.

Vue 및 React와 비교하여 Angular는 엄청 많은 파일을 가집니다. 하나의 큰 이유는 Vue가 한 컴포넌트의 모든 것을 하나의 파일에 집어 넣고 React가 CSS를 자체 파일로 나누는 반면 Angular는 css를 한 파일에, html을 다른 파일에, 컴포넌트 코드를 다른 파일에 넣습니다. 이 모든 것을 하나의 파일에 넣을 수는 있지만, 파일을 별도로 유지하는 것이 좋습니다.

또 다른 이유로는 Angular가 TypeScript를 사용한다는 것입니다. TypeScript는 "선택적 정적 입력, 클래스 및 인터페이스를 제공하는 JavaScript의 Superset"입니다. 풀어서 설명해보겠습니다.

TypeScript는 실제로 자바 스크립트 위에 여러 가지 요소를 추가합니다. TypeScript 코드에 JavaScript 행을 작성하면 정상적으로 작동합니다. TypeScript로 할 수있는 일은 클래스를 쉽게 만들고 클래스 사용을 강조하는 것입니다.

프로젝트에서 ToDo 클래스를 만듭니다.

export class ToDo {
constructor(item: string) {
  this.Item = item;
  }
Item: string;
}

이 클래스는 그 자체만으로는 많은 것을 하지 않습니다. 인수에 ToDo가 들어오는 함수를 작성할 수 있고, TypeScript 컴파일러는 다른 인자를 넣을 경우 오류를 내뱉을 것입니다.

예 :

function PrintToDo(myToDo: ToDo) { //인수는 ToDo 유형입니다.
console.log(myToDo.Item)
}
// 컴파일러 오류가 발생합니다.
this.PrintToDo("not a ToDo type")
//이 작업은 수행되지 않습니다.
this.PrintToDo(new ToDo("a real ToDo"))

물론 우리는 클래스가 아니라 원하는 모든 타입으로 이 작업을 수행 할 수 있습니다.

function PrintString(myString: string) {
console.log(myToDo)
}
// 컴파일러 오류가 발생합니다.
this.PrintToDo(new ToDo("not a string type"))
//이 작업은 수행되지 않습니다.
this.PrintToDo("A string!")

TypeScript는 기본적으로 JavaScript입니다. 타입 에러를 발생시키고, 자바스크립트에서 런타입 오류가 될 수 있는 어리석은 실수를 막아준다는 점만 제외하면요.

어플리케이션이 더 복잡해짐에 따라 이와 같은 클래스가 실제로 유용합니다! 제품, 직업 또는 사람과 같은 실제 생활을 위한 좋은 모델 역할을 합니다. Angular 세계에서는 이를 모델이라고 부릅니다.

어떻게 새로운 ToDos를 만들 수 있습니까?

ToDoComponent는 다음과 같습니다.

ToDoComponent (전체 코드)

이 컴포넌트의 대부분은 스타일 지정 및 입력 폼과 관련이 있습니다. ToDo 리스트 자체에 초점을 맞추어 보겠습니다.

ToDoComponent (축약형)

그것에 착수 할 때, 우리의 리스트 컴포넌트는 ToDos 리스트입니다. ngFor는 foreach가하는 것처럼 우리 리스트를 가져 와서 각 항목을 표시 할 수 있습니다. 큰 차이점은 Angular가 업데이트를 처리한다는 것입니다! 유효한 입력을 얻었으면 문자열을 새로운 ToDo 객체에 전달하고 그것을 리스트에 추가하기만 하면 됩니다. Angular는 나머지를 처리합니다!

this.ToDos = this.ToDos.concat(new ToDo(this.Input));

다 됐네요! 또한 사용자가 빈 ToDo를 만들지 않도록 하려면 어떻게 할까요?

Angular 폼 유효성 검사

Enter 키가 눌리는 것을 확인하거나 문자열 내용을 검사해서 오류를 던질 수 있도록 하는 대신 Angular Forms를 사용하여 이를 수행 할 수 있습니다. 전체 ToDoComponent를 살펴보시면, form 요소를 선언하고,

<form (ngSubmit) = "addItem ()"# todoForm = "ngForm">

ngSubmit 바인딩은 submit 버튼이 눌러 지거나 사용자가 enter를 누를 때 트리거됩니다! 폼이 유효한 상태 일 때만 트리거 될 수도 있습니다.

또한 ngForm은 폼의 각 입력에 대해 컴포넌트 멤버 변수를 만듭니다. 이 경우 이름은 name입니다. 입력이 어떤 상태인지 확인하고 오류 또는 기타 유용한 메시지를 표시 할 수 있습니다. 이 경우 valid,pristine을 사용하며, 우리는 이전에 폼이 제출되었는지 아닌지를 계속 추적합니다.

재미있는 사실은, Angular에서 사용자 정의 유효성 검사를 만들 수 있다는 것입니다! 지금 프로젝트에서는 필요하지 않지만 전화 번호를 정형화하여 유효성 검사를 할 수 있습니다! 깔끔하죠?

리스트를 다루고 있었습니다만, 실제적으로 ToDo는 어떻게 나타날까요?

ToDo Item 컴포넌트는 다음과 같습니다.

ToDo 아이템 컴포넌트

어떻게 데이터를 변경하나요?

Angular에서 일부 데이터를 표시하려면 다음 두 가지 작업을 수행해야 합니다.

  1. 이 컴포넌트에 멤버를 등록 시키십시오. (이 경우에는 ToDo)

  1. 중괄호 {{ToDo.Item}}이 있는 템플릿에서 이를 참조하십시오.

이게 전부입니다! ToDo.Item을 전혀 변경하지 않으면 Angular가 View를 업데이트합니다. React는 이러한 훅을 제공하지 않습니다. 왜냐하면 setState를 호출하는 것이 컴포넌트를 다시 렌더링 하기 때문입니다.

컴포넌트와 통신

이 컴포넌트는 하나의 ToDo 만 표시하는 것과 관련이 있으므로 ToDoComponent는 ToDo Item 컴포넌트에 표시 할 ToDo를 제공 할 수 있어야합니다! ToDoComponent에 사용자가 삭제 버튼을 클릭했음을 알릴 수 있어야합니다. Angular는 InputOutput으로 이를 수행합니다.

입력은 매우 간단하며, 우리가 원하는 모든 타입이 될 수 있으며 우리를 위해 묶일 것입니다! 이 컴포넌트에는 입력으로 ToDo만 있습니다. 우리는 Angular에게 특정한 멤버에 @Input() 데코레이터를 앞에 놓음으로써 입력이라고 말합니다.

@Input() ToDo: ToDo = new ToDo(""); 

그런 다음 상위 컴포넌트는 ToDoItem 컴포넌트에 ToDo를 전달해야합니다.

<ToDoItem [ToDo]=”ToDo”></ToDoItem>

그런 다음 ToDo를 표시하기 위해 바인딩을 사용합니다.

산출물은 조금 다릅니다. 출력은 단지 일부 데이터가 아니라, 해당 출력을 감시하는 모든 것을 트리거하는 이벤트이기도합니다. Angular Input은 (문자열과 같은) 모든 타입이 될 수 있지만 출력은 EventEmitter 타입을 따라야 합니다. EventEmitters는 비록 우리가 원하는 어떤 타입이라도 될 수있는 값을 emit합니다! 따라서 문자열을 출력하고 싶다면 다음과 같이 데코레이팅 된 멤버를 만들면됩니다.

@Output() Example: EventEmitter<string> = new EventEmitter();

상위 컴포넌트는 다음과 같은 이벤트를 구독 할 수 있습니다.

<ExampleComponent (Example)="exampleHandler($event)"></ExampleComponent>

이제 Output에 대한 지식으로 무장하게 되었습니다.. ToDo를 어떻게 삭제할까요?

ToDo 삭제하기

우리는 ToDoItem 컴포넌트에서 아무 것도 전달할 필요가 없습니다. 이벤트를 트리거하면됩니다. Typescript는 우리의 출력이 어떤 타입인지 알 필요가 있지만, 우리가 신경 쓰지 않기 때문에 그냥 any로 만듭니다. Output은 다음과 같이 보일 것입니다 :

@Output() Deleted: EventEmitter<any> = new EventEmitter();

ToDoItem 내에서 이벤트를 트리거해야합니다. Part 1에서 보았던 버튼 폼처럼 보이는 멋지게 정형화 된 div가 있습니다. 함수를 click 이벤트까지 연결해야합니다.

<div class="ToDoItem-Delete" (click)="deleteItem()">-</div>

그러면 deleteItemDeleted에서 .emit()를 호출합니다.

deleteItem() {
this.Deleted.emit();
}

Angular는 이벤트를 ToDoComponent까지 전달합니다.

우리의 ToDoComponent로 돌아가서 우리는 ToDoItem 컴포넌트에 deleteItem 함수를 바인딩했습니다. 또한 현재 ToDo의 인덱스를 전달하므로 삭제할 항목을 알 수 있습니다.

<div *ngFor="let ToDo of ToDos; index as i" >
  <ToDoItem [ToDo]="ToDo" (Deleted)="deleteItem(i)"></ToDoItem>
</div>

그런 다음 인덱스에서 ToDo를 제거하고 Angular가 화면을 업데이트하면됩니다.

deleteItem(i: number) {
this.ToDos.splice(i, 1);
}

자, ToDo List 애플리케이션이 만들어졌습니다!


작은 Angular 앱이라도 React 또는 Vue 앱보다 훨씬 더 많은 기능을 제공합니다. Angular에 대한 정말 좋은 점은 필요한 기능 대부분이 Angular 자체에 있다는 것입니다. Angular에는 페이지 라우팅, 페이지 액세스, HTTP 호출, 모듈 지연로드 등이 포함됩니다. 헤비급 프레임워크는 큰 학습 곡선을 가지고 있습니다. 그러나, 내가 필요한 것에 대한 해결책을 찾기 위해 Angular 외부로 갈 필요가 거의 없다는 것이 장점입니다.


읽어 주셔서 감사합니다! 트위터 @mibzman에서 당신이 생각한 것을 알려주세요! 이 글을 작성할 수 있는 계기를 만들어준 Sunil Sandhu에게 감사드립니다! Part 1을 아직 읽지 않으셨다면 여기에 링크가 있습니다. Github에 소스 코드를 확인하실 수 있습니다.

나는 올해 초 React Native vs Ionic에 관한 20장 분량의 내용을 작성했는데 읽고 싶다면 여기를 확인해보십시오.

Comments