TIL_171113 Angular interaction

컴포넌트 대상화
재사용의 가능성이 있는 부분이라면(기능) 컴포넌트화해서 분리

컴포넌트간 상태공유

1. 부모 -> 자식: 프로퍼티 바인딩, @Input

1-1) 부모 –> 보낼때

1
<child [state]="myState"></child>

1-2) –> 자식 받을때

1
@Input() state: string
  • 즉, [property-binding] state | myState
    -> ‘state’라는 하나의 매개체만을 가지고 느슨한 결합상태를 유지

Setter

users에 값을 할당하는 순간 (부모-> 자식에게 데이터전송하는 순간), users 내부에 설정한 함수(로직)이 실행

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 자식 컴포넌트
@Input()
set users(users: User[]) {
if (!users) { return; }
this.cntAdmin
= users.filter(({role}) => role === 'Administrator').length;
this.cntDeveloper
= users.filter(({role}) => role === 'Developer').length;
this.cntDesigner
= users.filter(({role}) => role === 'Designer').length;
this._users = users;
}
get users(): User[] {
return this._users;
}


2. 자식 -> 부모: 이벤트 바인딩, @Output

2-1) 자식 –> 보낼때

  • 앵귤러가 지원하는 EventEmitter을 통해 커스텀한 이벤트를 생성
  • -> 부모에게 데이터를 전달하는 역할
  • event명.emit을 통해 해당 이벤트 호출
  • -> 전달할 데이터를 인자에 담아 보냄
1
<button (click)="onClick(state)"> X </button>
1
2
3
4
5
6
// EventEmitter를 통해 커스텀 이벤트 생성: 데이터를 전달하는 역할
@Output() myEvent = new EventEmitter();
// 생성한 커스텀 이벤트 호출: 전달할 데이터를 인자에 담아 보냄-->
onClick(state){ ##do something## this.myEvent.emit(state);}

2-2) –> 부모 받을때

1
2
3
4
<child (myEvent)="myEventHandler($event)"></child>
// 부모는 커스텀 이벤트 (state) 바인딩을 받음
myEventHandler(state){ ##do something## }

자식 컴포넌트가 자신이 삭제하지 않고, 삭제하라고 부모에게 알리는 이유?
같은 참조값(주소)을 바라보고 있기 떄문에, 그 값을 변경하는 비순수함수의 역할을 부모, 자식 둘다 하게 할 경우 데이터의 변경이 어디서 이루어졌는지 알수가 없음

  • -> 부모자식관계의 깊이가 깊을 경우 데이터변경을 추적할 수 없어 코드의 예측성과 협업능력 저하
  • 즉, 컴포넌트를 Stateful / Stateless 로 역할분리하여 관리
  • Stateful: 상태 정보를 저장, 변경가능 (비순수, Smart)
  • Stateless: 정보를 표현만 (순수, Dumb)

특히, 데이터변경은 앵귤러의 변화감지가 일어나도록 해야 뷰에 표현되기 때문에 참조값(주소)을 변경하도록 하는것이 예측하기 좋음
(push와 같은 경우는 주소가 변경되지 않아 비추)


constructor 내부에 public 을 해준 이유는?
내부의 id, name, role은 public없이는 파라미터여서 생명주기가 constructor내부로 한정. 따라서 이 앞에 public을 붙여줌으로써 위에 멤버변수 선언을 한것과 동일한 효과를 줌

1
2
3
export class User {
constructor(public id: number, public name: string, public role: string) { }
}

쉐도우 DOM 스타일 셀렉터

1. :host

  • 호스트 요소(컴포넌트 자신)을 선택
  • 커스텀 생성한 태그()는 기본 html과 같이 inline, block과 같은 브라우저 기본 특징이 없음 -> height, width 초기값이 auto
  • 이럴 때에 :host를 통해 css { display: block } 설정 가능
  • 상태들에 대한 가상클래스 선언 가능 :host(:hover), :host(.active)

    2. :host-context

    • 호스트 요소의 외부(예를 들어 body)의 조건에 의해 컴포넌트의 요소를 선택
      1
      2
      3
      4
      5
      6
      /* 컴포넌트의 조상 요소에 theme-red 클래스가 선언되어 있을 때 적용된다. */
      :host-context(.theme-red) .btn-primary {
      color: #fff;
      background-color: crimson;
      border-color: crimson;
      }