diff --git a/public/docs/ts/latest/cookbook/component-communication.jade b/public/docs/ts/latest/cookbook/component-communication.jade
index ab87d707..d8588d59 100644
--- a/public/docs/ts/latest/cookbook/component-communication.jade
+++ b/public/docs/ts/latest/cookbook/component-communication.jade
@@ -2,206 +2,327 @@ include ../_util-fns
:marked
+ 이 쿡북은 두개 이상의 컴포넌트가 정보를 공유하는 주된 시나리오들에 대한 레시피들로 이루어져 있습니다.
+
This cookbook contains recipes for common component communication scenarios
in which two or more components share information.
//
.l-sub-section
:marked
+ 컴포넌트 간 통신에 대한 각각의 기본적인 개념에 대해 알고 싶다면, [컴포넌트 간 통신]() 문서에서 자세한 설명과 예시들을 찾아볼 수 있습니다.
+
For an in-depth look at each fundamental concepts in component communication, we can find detailed description and
samples in the [Component Communication]() document.
:marked
+ ## 목차
+
## Table of contents
-
+
+ [인풋 바인딩으로 부모 컴포넌트에서 자식 컴포넌트로 데이터 보내기](#parent-to-child)
+
[Pass data from parent to child with input binding](#parent-to-child)
+ [setter로 인풋 속성 변경 잡아내기](#parent-to-child-setter)
+
[Intercept input property changes with a setter](#parent-to-child-setter)
+ [*ngOnChanges*로 바뀌는 인풋 값을 잡아내기](#parent-to-child-on-changes)
+
[Intercept input property changes with *ngOnChanges*](#parent-to-child-on-changes)
+ [부모 컴포넌트가 자식 컴포넌트 event를 받아올 때](#child-to-parent)
+
[Parent listens for child event](#child-to-parent)
-
+
+ [*지역 변수*로 부모 컴포넌트와 자식 컴포넌트 간 상호작용하기](#parent-to-child-local-var)
+
[Parent interacts with child via a *local variable*](#parent-to-child-local-var)
-
+
+ [ViewChild를 이용해 부모 컴포넌트에서 자식 컴포넌트 불러오기](#parent-to-view-child)
+
[Parent calls a *ViewChild*](#parent-to-view-child)
+ [service를 통한 부모와 자식 컴포넌트 간 통신하기](#bidirectional-service)
+
[Parent and children communicate via a service](#bidirectional-service)
:marked
+ **예시는 여기를 참고하세요**.
+
**See the **.
.l-main-section
:marked
+
+ ## 인풋 바인딩으로 부모 컴포넌트에서 자식 컴포넌트로 데이터 보내기
+
## Pass data from parent to child with input binding
-
- `HeroChildComponent` has two ***input properties***,
+
+ `HeroChildComponent`는 두 개의 ***인풋 속성들***을 지니고 있고,
+ [@Input decorations](../guide/template-syntax.html#inputs-outputs)들로 꾸며져 있지요.
+
+ `HeroChildComponent` has two ***input properties***,
typically adorned with [@Input decorations](../guide/template-syntax.html#inputs-outputs).
-
+
+makeExample('cb-component-communication/ts/src/app/hero-child.component.ts')
:marked
+ 두 번째 `@Input`, 즉 인풋 속성은 자식컴포넌트의 속성 이름인 `masterName`를 `'master'`로 줄여줍니다.
+
The second `@Input` aliases the child component property name `masterName` as `'master'`.
-
- The `HeroParentComponent` nests the child `HeroChildComponent` inside an `*ngFor` repeater,
+
+ 그래서 그 부모인 `HeroParentComponent`는 그의 자식 컴포넌트 `HeroChildComponent`를 `*ngFor` 반복자 안에 넣고,
+ 부모의 `master` 스트링 타입 속성을 자식 컴포넌트의 `master` 바로가기에 묶고
+ 매 반복 때 마다 쓰이는 `hero` 인스턴스를 자식 컴포넌트의 `hero` 속성에 묶습니다.
+
+
+ The `HeroParentComponent` nests the child `HeroChildComponent` inside an `*ngFor` repeater,
binding its `master` string property to the child's `master` alias
and each iteration's `hero` instance to the child's `hero` property.
+makeExample('cb-component-communication/ts/src/app/hero-parent.component.ts')
:marked
+ 작동하는 웹 앱은 3명의 영웅들을 보여줍니다.
+
The running application displays three heroes:
-
+
figure.image-display
img(src="/resources/images/cookbooks/component-communication/parent-to-child.png" alt="Parent-to-child")
-
+
:marked
+ ### 테스트 해봅시다
+
### Test it
-
+
+ 자식 컴포넌트들을 위한 E2E test가 실행되었고 예상되로 결과가 보여집니다:
+
E2E test that all children were instantiated and displayed as expected:
-
+
+makeExample('cb-component-communication/e2e-spec.ts', 'parent-to-child')
:marked
+ [맨 위로](#top)
+
[Back to top](#top)
.l-main-section
:marked
+ ## setter로 인풋 속성 변경 잡아내기
+
## Intercept input property changes with a setter
+ 인풋 속성 setter를 써서 부모로부터 받은 값을 잡아내고 그에 대해 반응시켜보세요.
+
Use an input property setter to intercept and act upon a value from the parent.
-
- The setter of the `name` input property in the child `NameChildComponent`
- trims the whitespace from a name and replaces an empty value with default text.
-
+
+ 자식 컴포넌트 `NameChildComponent`에 있는 `name` 인풋 속성에 대한 setter는
+ 이름에 있는 띄어쓰기를 다듬고 기존에 정해진 텍스트로 비어진 값을 채워줍니다.
+
+ The setter of the `name` input property in the child `NameChildComponent`
+ trims the whitespace from a name and replaces an empty value with default text.
+
+makeExample('cb-component-communication/ts/src/app/name-child.component.ts')
:marked
+ 여기 `NameParentComponent`가 띄어쓰기만을 포함한 다양한 name 값에 대해 어떻게 대처하는지 보여줍니다.
+
Here's the `NameParentComponent` demonstrating name variations including a name with all spaces:
+makeExample('cb-component-communication/ts/src/app/name-parent.component.ts')
figure.image-display
img(src="/resources/images/cookbooks/component-communication/setter.png" alt="Parent-to-child-setter")
-
+
:marked
+ ### 테스트 해봅시다
+
### Test it
+ 비어있거나 안 비어있는 name값을 이용한 인풋 속성 setter 에 대한 E2E 테스트들:
+
E2E tests of input property setter with empty and non-empty names:
-
+
+makeExample('cb-component-communication/e2e-spec.ts', 'parent-to-child-setter')
:marked
+ [맨 위로](#top)
+
[Back to top](#top)
.l-main-section
:marked
+ ## *ngOnChanges* 로 인풋 속성 변경을 잡아내기
+
## Intercept input property changes with *ngOnChanges*
+ 컴포넌트의 생명주기 훅 인터페이스인 `OnChanges`의 `ngOnChanges` 메소드로 인풋 속성 변경을 감지하고 이에 대해 반응하게 해봅시다.
+
Detect and act upon changes to input property values with the `ngOnChanges` method of the `OnChanges` lifecycle hook interface.
.l-sub-section
:marked
+ 만약 여러개의 상호작용하는 인풋 속성을 지켜봐야 한다면 속성 setter 대신 이것을 추천합니다.
+
May prefer this approach to the property setter when watching multiple, interacting input properties.
-
+
+ [LifeCycle Hooks](../guide/lifecycle-hooks.html) 챕터에 있는 `ngOnChanges` 에 대해 알아보세요.
+
Learn about `ngOnChanges` in the [LifeCycle Hooks](../guide/lifecycle-hooks.html) chapter.
:marked
+ `VersionChildComponent`는 `major` 와 `minor` 인풋 속성을 인지하고 값들의 변경에 따라 log message를 작성합니다.
+
This `VersionChildComponent` detects changes to the `major` and `minor` input properties and composes a log message reporting these changes:
-
+
+makeExample('cb-component-communication/ts/src/app/version-child.component.ts')
:marked
+ `VersionParentComponent`는 `minor` 와 `major` 값들을 가지고 있고 값들을 변경하는 메소드를 이어주는 버튼을 보여줍니다.
+
The `VersionParentComponent` supplies the `minor` and `major` values and binds buttons to methods that change them.
-
+
+makeExample('cb-component-communication/ts/src/app/version-parent.component.ts')
:marked
+ 버튼을 눌렀을 때의 과정은 다음과 같습니다:
+
Here's the output of a button-pushing sequence:
-
+
figure.image-display
img(src="/resources/images/cookbooks/component-communication/parent-to-child-on-changes.gif" alt="Parent-to-child-onchanges")
-
+
:marked
+ ### 테스트 해봅시다
+
### Test it
-
- Test that ***both*** input properties are set initially and that button clicks trigger
+
+ 양 속성 모두 초기값이 세팅이 되어있고 버튼 클릭이 예정된 `ngOnChanges` 요청과 값을 일으키는지에 대한 테스트:
+
+ Test that ***both*** input properties are set initially and that button clicks trigger
the expected `ngOnChanges` calls and values:
-
+
+makeExample('cb-component-communication/e2e-spec.ts', 'parent-to-child-onchanges')
:marked
+ [맨 위로](#top)
+
[Back to top](#top)
.l-main-section
:marked
+ ## 부모 컴포넌트가 자식 컴포넌트 event를 받아올 때
+
## Parent listens for child event
- The child component exposes an `EventEmitter` property with which it `emits`events when something happens.
+ 자식 컴포넌트는 뭔가 일어 났을 때 event들을 `보여주는` `EventEmitter` 속성을 (부모 컴포넌트에게)드러냅니다.
+
+ The child component exposes an `EventEmitter` property with which it `emits`events when something happens.
The parent binds to that event property and reacts to those events.
-
- The child's `EventEmitter` property is an ***output property***,
+
+ 자식 컴포넌트의 `EventEmitter` 속성은 ***출력 속성***에 속하고, 전형적으로 아래 `VoterComponent`에서 보여지는 것처럼 꾸며집니다:
+
+ The child's `EventEmitter` property is an ***output property***,
typically adorned with an [@Output decoration](../guide/template-syntax.html#inputs-outputs)
as seen in this `VoterComponent`:
-
+
+makeExample('cb-component-communication/ts/src/app/voter.component.ts')
:marked
+ 버튼을 클릭하면 (불리언 *페이로드*)인 `true` 나 `false` 값을 보내게 됩니다.
+
Clicking a button triggers emission of a `true` or `false` (the boolean *payload*).
-
+
+ 부모 컴포넌트인 `VoteTakerComponent`는 (`onVoted`) 이벤트 핸들러를 묶고 자식 이벤트 페이로드인 (`$event`)에 반응하여
+ 카운터를 갱신해줍니다.
+
The parent `VoteTakerComponent` binds an event handler (`onVoted`) that responds to the child event
payload (`$event`) and updates a counter.
-
+
+makeExample('cb-component-communication/ts/src/app/votetaker.component.ts')
:marked
- The framework passes the event argument — represented by `$event` — to the handler method,
+ 이 프레임워크는 이벤트 변수— 즉 `$event`를— 핸들러 메소드로 넘겨주고, 메소드는 그것을 처리합니다.
+
+ The framework passes the event argument — represented by `$event` — to the handler method,
and the method processes it:
-
+
figure.image-display
img(src="/resources/images/cookbooks/component-communication/child-to-parent.gif" alt="Child-to-parent")
-
+
:marked
+ ### 테스트 해봅시다
+
### Test it
-
+
+ *Agree* 와 *Disagree* 버튼들을 클릭하면 적절한 카운터들을 갱신시키는지 테스트:
+
Test that clicking the *Agree* and *Disagree* buttons update the appropriate counters:
-
+
+makeExample('cb-component-communication/e2e-spec.ts', 'child-to-parent')
:marked
+ [맨 위로](#top)
+
[Back to top](#top)
.l-main-section#parent-to-child-local-var
:marked
+ ## *지역 변수*로 부모 컴포넌트와 자식 컴포넌트 간 상호작용하기
+
## Parent interacts with child via *local variable*
-
+
+ 부모 컴포넌트는 데이터 바인딩으로 자식 컴포넌트의 속성을 읽어오거나
+ 자식 컴포넌트의 메소드들을 불러낼 수 없습니다. 하지만 자식 컴포넌트 속성에 대한 template reference 변수
+ 를 만들어 낸 다음 그 변수를 *부모 컴포넌트 template 안에* 언급할 수 있습니다.
+ 마치 아래에 있는 예시처럼 말이죠.
+
A parent component cannot use data binding to read child properties
- or invoke child methods. We can do both
+ or invoke child methods. We can do both
by creating a template reference variable for the child element
and then reference that variable *within the parent template*
as seen in the following example.
+ 여기서 우리는 0까지 아래로 세고 로켓을 발사하는 자식 컴포넌트 `CountdownTimerComponent`가 있군요.
+ 카운트다운을 하는 시계를 제어하는 `start` 와 `stop`를 메소드를 가지고 있고 카운트다운 상태 메시지를 자신의 template에
+ 보여줍니다.
+
We have a child `CountdownTimerComponent` that repeatedly counts down to zero and launches a rocket.
It has `start` and `stop` methods that control the clock and it displays a
countdown status message in its own template.
+makeExample('cb-component-communication/ts/src/app/countdown-timer.component.ts')
:marked
+ 그 '타이머 컴포넌트'(CountdownTimerComponent)를 보여주는 `CountdownLocalVarParentComponent`를 보도록 하죠.
+
Let's see the `CountdownLocalVarParentComponent` that hosts the timer component.
-
+
+makeExample('cb-component-communication/ts/src/app/countdown-parent.component.ts', 'lv')
:marked
- The parent component cannot data bind to the child's
+ 부모 컴포넌트는 자식 컴포넌트의 `start` 와 `stop` 메소드들에 대해 데이터 바인딩을 할 수 없으며
+ `seconds` 속성에 대해서도 할 수 없습니다.
+
+ The parent component cannot data bind to the child's
`start` and `stop` methods nor to its `seconds` property.
-
+
+ 이 때 자식 컴포넌트를 가리키는 지역변수 (`#timer`)를 (``)라는 태그 안에 지정해줍니다.
+ 이는 자식 컴포넌트를 가리키는 레퍼런스가 생기고 자식 컴포넌트의 *모든 속성과 메소드들*을 부모 컴포넌트 template 안에서 액세스할 수 있습니다.
+
We can place a local variable (`#timer`) on the tag (``) representing the child component.
That gives us a reference to the child component itself and the ability to access
*any of its properties or methods* from within the parent template.
-
+
+ 이번 예시에서는, 부모 컴포넌트의 버튼을 자식 컴포넌트의 `start` 와 `stop` 버튼에 연결시키고
+ 보간을 이용하여 자식 컴포넌트의 `seconds` 속성을 보여줍니다.
+
In this example, we wire parent buttons to the child's `start` and `stop` and
use interpolation to display the child's `seconds` property.
-
+
+ 아래 예시에서는 부모와 자식 컴포넌트가 어떻게 같이 움직이는지 보여줍니다.
+
Here we see the parent and child working together.
figure.image-display
@@ -209,123 +330,214 @@ figure.image-display
a(id="countdown-tests")
:marked
+ ### 테스트 해봅시다
+
### Test it
-
+
+ 부모 컴포넌트에서 보여주는 숫자 template이 자식 컴포넌트의 상태 메세지와 일치하는지 테스트해봅시다.
+ 또한 *Stop* 버튼을 클릭함으로서 카운트다운 타이머를 멈출 수 있는지도 테스트해봅시다:
+
Test that the seconds displayed in the parent template
match the seconds displayed in the child's status message.
Test also that clicking the *Stop* button pauses the countdown timer:
-
+
+makeExample('cb-component-communication/e2e-spec.ts', 'countdown-timer-tests')
:marked
+ [맨 위로](#top)
+
[Back to top](#top)
-
+
.l-main-section
:marked
+ ## *ViewChild*를 이용해 부모 컴포넌트에서 자식 컴포넌트 불러오기
+
## Parent calls a *ViewChild*
-
- The *local variable* approach is simple and easy. But it is limited because
+
+ *지역 변수*를 이용한 방법은 간단하고 쉽습니다. 하지만 이 방법은 제한적인데요. 왜냐하면 부모-자식 간의
+ 연결이 모두 다 부모 컴포넌트 안의 template 안에서 이루어져야 하기 때문입니다.
+ 부모 컴포넌트 그 *자신*은 자식 컴포넌트에 액세스할 수 없는 것이지요.
+
+ The *local variable* approach is simple and easy. But it is limited because
the parent-child wiring must be done entirely within the parent template.
The parent component *itself* has no access to the child.
-
+
+ 만약 부모 컴포넌트 *클래스*의 인스턴스가 자식 컴포넌트의 값을 읽고 써야 한다거나 자식 컴포넌트의 메소드를 불러와야 한다면
+ *지역 변수* 를 이용한 방법을 사용할 수 없습니다.
+
We can't use the *local variable* technique if an instance of the parent component *class*
must read or write child component values or must call child component methods.
-
- When the parent component *class* requires that kind of access,
+
+ 부모 컴포넌트 *클래스*가 이러한 액세스를 필요로 한다면,
+ 부모 컴포넌트에 자식 컴포넌트를 *ViewChild*로 ***주입*** 시키세요.
+
+ When the parent component *class* requires that kind of access,
we ***inject*** the child component into the parent as a *ViewChild*.
-
- We'll illustrate this technique with the same [Countdown Timer](#countdown-timer-example) example.
- We won't change its appearance or behavior.
+
+ 우리는 이 기술을 같은 예시인 [카운트다운 타이머](#countdown-timer-example)로 구현해볼 것입니다.
+ view이나 행동을 바꾸지 않고서 말이죠.
+ 자식 컴포넌트 [CountdownTimerComponent](#countdown-timer-example)도 마찬가지입니다.
+
+ We'll illustrate this technique with the same [Countdown Timer](#countdown-timer-example) example.
+ We won't change its appearance or behavior.
The child [CountdownTimerComponent](#countdown-timer-example) is the same as well.
.l-sub-section
:marked
+ 우리는 설명을 위해 오직 *지역변수*에서 *ViewChild*를 이용한 기술로 바꾸기만 할 것입니다.
+
We are switching from the *local variable* to the *ViewChild* technique
solely for the purpose of demonstration.
:marked
+ 여기 부모인 `CountdownViewChildParentComponent`가 있습니다:
+
Here is the parent, `CountdownViewChildParentComponent`:
+makeExample('cb-component-communication/ts/src/app/countdown-parent.component.ts', 'vc')
:marked
+ 자식 컴포넌트의 view를 부모 컴포넌트 *클래스*에 구현하기 위해서는 조금 더 많은 노력이 필요합니다.
+
It takes a bit more work to get the child view into the parent component *class*.
-
+
+ `ViewChild` 데코레이터와 and the `AfterViewInit` 생명주기 훅 에 대한 레퍼런스를 들여옵니다.
+
We import references to the `ViewChild` decorator and the `AfterViewInit` lifecycle hook.
-
+
+ 자식 컴포넌트인 `CountdownTimerComponent`를 `@ViewChild` property decoration으로 private 속성인
+ `timerComponent`에 주입시켜 줍니다.
+
We inject the child `CountdownTimerComponent` into the private `timerComponent` property
via the `@ViewChild` property decoration.
-
- The `#timer` local variable is gone from the component metadata.
+
+ `#timer` 지역변수는 메타 데이터(태그)에서 사라졌습니다.
+ 대신 버튼들을 부모 컴포넌트의 `start` 와 `stop` 메소드에 연결시키고
+ 보간을 이용해 초가 지나가는 것을 부모 컴포넌트의 `seconds` 메소드로 보여줍니다.
+
+ The `#timer` local variable is gone from the component metadata.
Instead we bind the buttons to the parent component's own `start` and `stop` methods and
present the ticking seconds in an interpolation around the parent component's `seconds` method.
-
+
+ 이 메소드들은 주입된 타이머 컴포넌트에 직접 액세스 합니다.
+
These methods access the injected timer component directly.
-
+
+ `ngAfterViewInit` 생명주기 훅은 매우 중요한 방법입니다.
+ 이를 이용하면 타이머 컴포넌트는 앵귤러가 부모 컴포넌트의 view를 보여준 *후* 까지는 접근이 불가능합니다.
+ 그래서 초기값으로 `0`을 보여줍니다.
+
The `ngAfterViewInit` lifecycle hook is an important wrinkle.
The timer component isn't available until *after* Angular displays the parent view.
So we display `0` seconds initially.
-
+
+ 그 후엔 앵귤러는 `ngAfterViewInit` 생명주기 훅을 부모 컴포넌트 view의 모습을 카운트다운 초로 갱신하기 에
+ *너무 늦을 때* 불러냅니다.
+ 앵귤러의 방향이 정해지지 않은 데이터 흐름 규정은 부모 컴포넌트 view를 같은 주기에서 갱신시키는 것을 미리 막게 해줍니다.
+ 그래서 초를 보여주기 전에 *한 번 기다려야* 합니다.
+
Then Angular calls the `ngAfterViewInit` lifecycle hook at which time it is *too late*
to update the parent view's display of the countdown seconds.
Angular's unidirectional data flow rule prevents us from updating the parent view's
in the same cycle. We have to *wait one turn* before we can display the seconds.
-
- We use `setTimeout` to wait one tick and then revise the `seconds` method so
+
+ `setTimeout`을 이용해 1초가 지나가는 것을 기다리고 `seconds` 메소드가
+ 타이머 컴포넌트로부터 나중에 들어올 값을 받을 수 있게 수정해줘야 힙니다.
+
+ We use `setTimeout` to wait one tick and then revise the `seconds` method so
that it takes future values from the timer component.
+ ### 테스트 해봅시다
+
### Test it
+
+ [전에 했던 카운트다운 타이머 테스트들](#countdown-tests)를 사용하십시오.
+
Use [the same countdown timer tests](#countdown-tests) as before.
:marked
+ [맨 위로](#top)
+
[Back to top](#top)
-
+
.l-main-section
:marked
+ ## service를 통한 부모와 자식 컴포넌트 간 통신하기
+
## Parent and children communicate via a service
+ 하나의 부모 컴포넌트와 그것의 자식 컴포넌트들은 *가족 내에서* 쌍방향 통신이 가능하게 하는 인터페이스를 가진 service를 공유한다고 해봅시다.
+
A parent component and its children share a service whose interface enables bi-directional communication
*within the family*.
- The scope of the service instance is the parent component and its children.
+ 이 service 인스턴스의 범위는 부모 컴포넌트와 그 자식들입니다.
+ 이 컴포넌트의 가족구도를 벗어난 컴포넌트들은 그들이 가지고 있는 service나 통신에 접근할 수 없습니다.
+
+ The scope of the service instance is the parent component and its children.
Components outside this component subtree have no access to the service or their communications.
-
+
+ 이 `MissionService`는 `MissionControlComponent`를 여러 개의 `AstronautComponent` 자식 컴포넌트들에 연결시킵니다.
+
This `MissionService` connects the `MissionControlComponent` to multiple `AstronautComponent` children.
+makeExample('cb-component-communication/ts/src/app/mission.service.ts')
:marked
+ `MissionControlComponent` 는 자식 컴포넌트와 공유하는 service 인스턴스를 제공하고(`providers` 메타데이터 배열을 통해서)
+ 그 인스턴스를 자신의 건설자에 주입합니다.
+
The `MissionControlComponent` both provides the instance of the service that it shares with its children
(through the `providers` metadata array) and injects that instance into itself through its constructor:
-
+
+makeExample('cb-component-communication/ts/src/app/missioncontrol.component.ts')
:marked
+ `AstronautComponent` 또한 service를 건설자에 주입시킵니다.
+ `AstronautComponent`는 `MissionControlComponent`의 자식 컴포넌트이므로 부모 컴포넌트의 서비스 인스턴스를 물려받습니다.
+
The `AstronautComponent` also injects the service in its constructor.
Each `AstronautComponent` is a child of the `MissionControlComponent` and therefore receives its parent's service instance:
-
+
+makeExample('cb-component-communication/ts/src/app/astronaut.component.ts')
.l-sub-section
:marked
+ 위 예시가 `subscription`을 잡을 수 있다는 것과 `AstronautComponent`가 파괴되었을 때 구독을 취소할 수 있다는 것에 주목하십시오.
+ 이것은 메모리 누수를 막기 위한 과정입니다. `AstronautComponent` 의 생명 주기는 앱의 생명주기와 같기 때문에 이 앱에서 실제로 문제가 될 만한 일은 없습니다.
+ 이것은 그러나 복잡한 구조의 앱에서는 항상 참이 *아닙니다*.
+
Notice that we capture the `subscription` and unsubscribe when the `AstronautComponent` is destroyed.
This is a memory-leak guard step. There is no actual risk in this app because the
lifetime of a `AstronautComponent` is the same as the lifetime of the app itself.
That *would not* always be true in a more complex application.
-
+
+ `MissionControlComponent`에는 이러한 예방책을 적용할 수 없는데, 이는 부모 컴포넌트로서
+ `MissionService`의 생명주기를 제어할 수 있기 때문입니다.
+
We do not add this guard to the `MissionControlComponent` because, as the parent,
it controls the lifetime of the `MissionService`.
:marked
+ *History* 기록은 service에 의해 만들어진 부모인 `MissionControlComponent`와 자식인 `AstronautComponent`
+ 사이의 양방향 메세지들을 보여줍니다.
+
The *History* log demonstrates that messages travel in both directions between
the parent `MissionControlComponent` and the `AstronautComponent` children,
facilitated by the service:
-
+
figure.image-display
img(src="/resources/images/cookbooks/component-communication/bidirectional-service.gif" alt="bidirectional-service")
-
+
:marked
+ ### 테스트 해봅시다
+
### Test it
-
+
+ 부모 컴포넌트 `MissionControlComponent`와 자식 컴포넌트 `AstronautComponent`의 클릭 버튼들을 둘 다 테스트 해보고
+ 예상한 대로 *History*가 기록되어 있는지 확인:
+
Tests click buttons of both the parent `MissionControlComponent` and the `AstronautComponent` children
and verify that the *History* meets expectations:
-
+
+makeExample('cb-component-communication/e2e-spec.ts', 'bidirectional-service')
:marked
+ [맨 위로](#top)
+
[Back to top](#top)