두서없는 앵귤러 정리

noyo0123·2020년 2월 13일
0

컴포넌트

NgModule

declarations, imports 차이는?
declarations는 하위 컴포넌트를 사용할때 사용.
imports는 하위 컴포넌트가 다른 모듈의 일부분을 가져와야할때 사용.
아직까지는.. 와닫지 않음.

컴포넌트간 상태공유

자식 컴포넌트에서 부모 컴포넌트로 상태 전달

부모가 자식한테 상태 전달할때는 @Input 데코레이터 사용했음.

자식 컴포넌트 ---> 부모 컴포넌트
myEvent, state가 함께 전달.


이벤트 바인딩

이벤트 바인딩 : 뷰의 상태 변화 ( 버튼 클릭, 체크박스 체크, input에 텍스트 입력 등 )에 의해 이벤트가 발생하면 이벤트 핸들러를 호출하는 것

컴포넌트 클래스와 템플릿 연동

예를 들어 앵귤러 방식으로 button을 만들고 그 이벤트를 달아서

컴포넌트 클래스 ( 상태) ----데이터바인딩 ---- 템플릿

app.component.ts

이벤트 흐름 :
텍스트 입력에 의해 input 이벤트 발생하면 이벤트 바인딩을 통하여 이벤트 핸들러 setName을 호출한다.
$event를 통해 DOM 이벤트 객체를 이벤트 핸들러에 전달할 수 있음.
angular는 표준 DOM이벤트를 사용하기 때문에 $event를 통해 브라우저의 Event객체의 프로퍼티나 메서드를 자유롭게 접근할 수 있음.

정리

input 태그의 경우는 input event가
select 태그에는 change event가 발생합니다.
이 이벤트들은 HTML DOM Events의 이벤트입니다.
앵귤러는 표준 DOM Event를 사용하기 때문입니다.


커스텀 이벤트 배출하기

  1. @Component 설정에 output 지정
  2. 출력 프로퍼티에 EventEmitter 연결
  3. EventEmitter 에서 제때 이벤트 배출하기

EventEmitter 는 옵저버 패턴의 구현을 지원하는 객체

  1. 구독자 리스트 관리
  2. 구독자에게 이벤트 발행

@ViewChild

요거 뭐냐면
부모 컴포넌트에서
@ViewChild('childComp') myChild: ChildComponent; 이렇게 사용하면, 자식 컴포넌트의 프로퍼티 직접 변경하고, 자식 컴포넌트의 메소드를 직접 실행할 수도 있음.
this.myChild가 레퍼런스 변수가 되는거임.

템플릿에서는 참조변수로 쓸 수 있음.
이걸 어따 쓰나.. 네이티브 DOM이나 자식 컴포넌트에 직접 참조할때 쓰인다는데 아직은 모르겠음.

@ViewChildren은 myChild가 리스트형태이다.


angular 폼

FormControl

쉽게 얘기해서 입력필드
입력필드에 관련된 데이터를 갖고있는 객체

FormGroup

앵귤러를 처음 접해서 이게 뭔지 모름 그래서 정리

이전에는
<input type="text" name="product-name" [(ngModel)]="product.name" />
이렇게 썼었고,

NgModel 지시자는 FormsModule에 포함되어 있기 때문에 NgModel로 양방향 바인딩을 사용하려면 FormsModule을 우리의 모듈에 임포트 해야합니다.
앵귤러 CLI로 프로젝트 생성한 경우 디폴트로 AppModule에 임포트 되어있음.

폼의 구성

앵귤러에서는 폼의 모든 요소를 추상화하여 모델클래스?와 지시자의 조합?으로 구성하여 제공합니다.

폼을 다루는 요소의 핵심 FormControl 클래스?

FormControl은 폼에서 사용자 입력을 받는 모든 요소에 일대일로 대응하는 모델 클래스입니다. 앵귤러는 우리가 작성한 템플릿의 폼을 파싱하여 모든 입력 요소마다 FormControl 클래스?를 하나씩 생성합니다.

사용자가 입력한 값의 상태 및 변경 이벤트의 기본적인 구현부는 AbstractControl에 있습니다.
입력 요소의 실제 값이 선언된 곳은 AbstractControl입니다.
AbstractControl의 _value속성이 선언되어 있으며, 입력 요소의 실제 값은 AbstractControl에 선언된 _value에 저장됩니다.

사용자의 입력을 받는 요소가 FormControl 객체가 되고, 이를 모아서 FormGroup으로 묶을 수 있습니다.

반응형 폼(모델? 주도 폼)

반응형 폼은 템플릿 주도 폼과 달리 폼을 구성하는 구현 코드를 템플릿이 아닌 컴포넌트에 작성합니다.

컴포넌트 클래스에서 폼에 대응하는 모델?을 기반으로 폼을 구성하기 때문에 모델 주도 폼이라고 부르기도 합니다. 이미 앞에서 살펴보았던 템플릿 주도 폼에서 템플릿에 NgModel, NgForm과 같은 지시자로 폼을 작성하였습니다. 내부적으로 앵귤러는 NgModel에 대응하여 Form 객체를 만들고, NgForm에 대응하여 FormGroup 객체를 생성했음.

반응형 폼 방식은 템플릿에 선언된 지시자를 기준으로 내부적으로 알아서 FormControl만들고, FormGroup을 구성하였던 것을 컴포넌트에서 우리가 직접 작성하는 것뿐

ReactiveFormsModule

클래스명 선택자 이름
FormControlDirective formControl FormControl 객체 바인딩
FormGroupDirective formGroup FormControl 객체 바인딩
FormControlName formControlName FormGroup에 포함된 FormControl 객체 바인딩

FormGroup, FormControl등 객체를 DOM의 폼 요소에 바인딩 할때 사용.
Directive는 독립적인 객체를 DOM에 바인딩할때 사용.

사용법

템플릿에 폼과 바인딩

FormGroup지시자를 사용하여 프로퍼티 바인딩으로 컴포넌트의 FormGroup을 하나 생성하였다고 가정..

FormControlName 지시자는 컴포넌트에서 선언한 FormGroup의 각 FormControl을 템플릿의 입력 요소와 바인딩할 때 사용합니다.

예를 들어, FormBuilder를 사용하여 컴포넌트에서 name키로 하는 FormControl을 포함하는 FormGroup이 있다면 formControlName 지시자에 문자열로 전달하면 됩니다.

정리: formGroup안에 있는 formControl의 상태가 Formbuilder로 생성한 group으로 생성한 객체에 상태들이 포함되어있고, 템플릿에 연결하기 위해서는 객체의 key를 formControlName 지시자의 바인딩에 넣어주면 this.myFormGroup은 템플릿에서 설정한 form값의 상태를 갖게 된다.


라이프사이클

ngOnChanges:

부모컴포넌트에서 자식컴포넌트의 입력프로퍼티 (@Input 데코레이터로 장식된 프로퍼티)로 바인딩한 값이 초기화 또는 변경되었을 때 실행된다.
기본 자료형의 값이 재할당되었을 때와 객체의 참조가 변경되었을 때만 반응한다.

ngOnInit:

모든 퍼로퍼티의 초기화가 완료된 시점에 한번 호출
constructor는 앵귤러랑 관계없어서, 프로퍼티 초기화는 ngOnIt에서 수행하는걸 권장

ngDoCheck:

ngOnInit 이후, 컴포넌트 또는 디렉티브의 모든 상태 변화가 발생할 때마다 호출됌.


데이터 바인딩

https://poiemaweb.com/angular-component-data-binding

NgModel과 양방향 바인딩

양방향 데이터 바인딩은 뷰와 컴포넌트 클래스의 상태변화를 상호 반영하는 것을 말함.
즉, 뷰의 상태가 변하는 컴포넌트의 클래스의 상태가 변하고, vice versa

NgModel 디렉티브는 앞에서 살펴본 바와 같이 폼 컨트롤 요소의 값과 유효성 검증 상태를 관리하는 FormControl 인스턴스를 생성한다고 하였다. 그런데 NgModel 디렉티브에 프로퍼티 바인딩을 사용하여 상태 프로퍼티를 바인딩하는 경우, 폼 컨트롤 요소의 상태 값을 업데이트할 수 있음.

하지만 엄밀히 말하면 양방향 바인딩은 존재하지 않습니다.

내부적으로 프로퍼티 바인딩과 이벤트 바인딩을 쓰죠.

다음과 같은 템플릿이 있다고 가정합니다.

[(ngModel)]은 내부적으로 아래와 같이 동작합니다.

[ngModel]="budget", (ngModelChange)="budget =$event"

budget이 input이 변할때마다 값이 변하죠.
즉 템플릿 <---> 컴포넌트 양방향으로 데이터가 바인딩 되고있습니다.

양방향 바인딩은 개발 편의를 위한 syntax라고 봐야겠죠.

이벤트 바인딩과 프로퍼티 바인딩의 축약 버전입니다.

출처: https://dschci.tistory.com/84?category=978065 [IT 회사에서 즐겁게 지내기!]

양방향 바인딩은 반드시 NgModel 디렉티브를 사용하여야 하는 것은 아니며 커스텀 양방향 데이터 바인딩도 작성할 수 있습니다. 커스텀 양방향 바인딩의 간단한 예제도 작성


내장 지시자

ngIf, ngSwitch, ngStyle, ngClass, ngFor
지시자는 동적 데이터 출력할 뿐 사용자 인터랙션을 생성하지 못함.


옵저버블

출처:
https://feel5ny.github.io/2018/03/25/angular_observable/

옵저버블은 앵귤러 고유 기능 ES7 스펙으로 제안되어 있는 비동기 데이터를 처리하기 위한 표준입니다.

Angular 필수 패키지 Rxjs는 비동기 데이터 스트림을 처리하는 API를 제공하는 자바스크립트 라이브러리이다.

HTTP 요청은 비동기 ( 요청에 대한 응답을 대기하지 않고 다음 작업을 할 수 있다. )
비동기처리는 프로미스! -> 옵저버블

RxJS의 원리는 Observable은 일련의 데이터를 발생시키는 원천?
Ajax 통신결과, 웹 소켓, 사용자 이벤트 등 데이터를 만들어 내는 것은 무엇이든 Observableㄹ 만들 수 있음.


에러

ExpressionChangedAfterItHasBeenCheckedError
자식컴포넌트에서 셀렉트박스를 그린후에 부모컴포넌트에서 셀렉트 박스에 들어갈 데이터를 전달하는 상황에서
발생했음.
부모컴포넌트에서 afterViewInit 사이클에서 데이터를 자식 컴포넌트에서 전달할 데이터를 참조했으나,
ExpressionChangedAfterItHasBeenCheckedError 가 발생해서 부모컴포넌트에서 Docheck 사이클에서 데이터를 전달하니 문제없이 해결이 됩니다.

profile
자바스크립트를 주언어로 개발을 배우고 있습니다. 서로 아는 것들을 공유해요~

0개의 댓글