{"action":"created","comment":{"url":"https://api.github.com/repos/angular/angular.io/pulls/comments/48581614","id":48581614,"diff_hunk":"@@ -0,0 +1,707 @@\n+include ../../../../_includes/_util-fns\n+\n+:marked\n+  ## Component Communication\n+\n+  Real applications rarely use a single component to implement the entire functionality of the app. To create structured, testable \n+  and maintainable applications, we'd better decompose the entire logic into a set of loosely-coupled (or decoupled) components.\n+  This way, we can create smaller building blocks with their own boundaries of responsibility, and compose the entire application\n+  from them.\n+  \n+  Generally, an Angular app is a tree of components &mdash; with the bootstrapped component in its root. Thinking of an app's \n+  structure as a tree, there are components that are in the same branch of the component tree &mdash; these form parent and child hierarchies\n+  &mdash;, and components in different branches &mdash; they are not directly related. Evidently, components need to communicate with each other\n+  to carry out the tasks the app is created for.\n+  \n+  As we already learned, _component_ is a pivotal concept of Angular, and it was designed with _inter-component communication_ in mind.\n+  We can think of the following information flows:\n+  * From a parent to its children\n+  * From a child to its parent\n+  * Among unrelated, completely decoupled components\n+  \n+  In this chapter, we will learn six frequently used Angular mechanisms and techniques available for inter-component communication.\n+  We will also get acquainted with the tradeoffs of each mechanism, and understand the scenarios best suited for using a particular method of communication.\n+  Before diving deeply into the details, here is a short overview of these techniques:\n+  \n+  __#1: Parent to child communication with input property binding__\n+  \n+  The `prop-value` expression of the parent is bound to the `child-prop` input property of the child. `child-prop` is updated every time when `prop-value` changes:\n+  \n++makeExample('component-communication/ts/fragments/property-binding-intro.html')\n+  \n+:marked\n+  We can bind multiple properties of a single child component to the parent, and, implicitly, we can bind multiple children to the parent &mdash; \n+  ie. with `ng-for`:\n+  \n++makeExample('component-communication/ts/fragments/property-binding-intro-2.html')\n+  \n+:marked\n+  [Jump to details](#-1-parent-to-child-communication-with-input-property-binding)\n+\n+:marked\n+  __#2: Child to parent communication with event emitting__\n+  \n+  When a child needs to communicate with its parent, it can emit an event. The parent can define  its own event handler method , and bind this method \n+  to the child's output property:\n+\n++makeExample('component-communication/ts/fragments/event-binding-intro.html')\n+  \n+:marked\n+  Here, the child event is emitted by the `raiseMyEvent` method. The parent declares the `handleMyEvent()` method and binds it to the `child-event`\n+  output property of the child. Events can have arguments &mdash; here, `\"Fired!\"` is the argument &mdash;, which can be passed to the parent.\n+  At the parent side `$event` represents the argument of the emitted event.\n+  \n+  [Jump to details](#-2-child-to-parent-communication-with-event-emitting)\n+\n+  __#3: Child to parent communication with direct method calling__\n+  \n+  Nothing prevents us to implement our parent so that it passes a reference to itself to its children, and those use that reference\n+  to access their parent's methods and properties. When the parent embeds its children as content markup, we can hand the parent reference to \n+  children in a trivial way like this:\n+  \n++makeExample('component-communication/ts/fragments/parent-reference-1.html')\n+  \n+:marked\n+  Beside this very technique, there are other ways to pass the parent reference to children, with little tricks we can even use dependency injection\n+  to inject the parent into the child component's constructor.\n+  The concrete technique does not matter: **Angular discourages this model, because it can sidestep the change detection mechanism, and so it may break\n+  the data flow model.**\n+  \n+  [Jump to details](#-3-child-to-parent-communication-with-direct-method-calling)\n+\n+  __#4: Duplex parent/child communication through a service object__\n+  \n+  Parent and child components share their responsibilities. In this sharing both component types have their own responsibilities including UI logic\n+  and others. The parent and its children both can manage state information about the UI logic. Often, the majority of communication is about\n+  managing the overall state information of this component fabric.\n+  \n+  In many cases the logic can be outsourced to a separate service that is the single source of truth, stores the state and provides operations to\n+  access and alter the state. In such a scenario, parent and child components do not need to talk with each other directly, each of them \n+  communicates with the intermediary service:\n+  \n++makeExample('component-communication/ts/fragments/service-intro.ts', 'service')\n+\n+:marked\n+  This service is injected into the parent and child components via Angular dependency injection (via component constructors):\n+\n++makeExample('component-communication/ts/fragments/service-intro.ts', 'components')\n+\n+:marked\n+  Both component types can access the service instance injected into the constructor. The dependency injection mechanism takes care &mdash; \n+  unless we do not configure it in another way &mdash; that the parent and its child components use the same service instance.\n+  We can design and implement the approprate service methods and properties, and access them from within the components. \n+  \n+  [Jump to details](#-4-duplex-parent-child-communication-through-a-service-object)\n+\n+  __#5: Communication among unrelated components via a message bus__\n+  \n+  In many inter-component communication scenario, the communicating parties are not in a perent-child relation with each other. They can\n+  be siblings, located in separate branches of the component hierarchy, or even be totally unrelated to each other. ","path":"public/docs/ts/latest/guide/component-communication.jade","position":99,"original_position":99,"commit_id":"c2b8f95f36484baaebc4e374aed9618d4a85f8fa","original_commit_id":"c2b8f95f36484baaebc4e374aed9618d4a85f8fa","user":{"login":"wardbell","id":129061,"avatar_url":"https://avatars.githubusercontent.com/u/129061?v=3","gravatar_id":"","url":"https://api.github.com/users/wardbell","html_url":"https://github.com/wardbell","followers_url":"https://api.github.com/users/wardbell/followers","following_url":"https://api.github.com/users/wardbell/following{/other_user}","gists_url":"https://api.github.com/users/wardbell/gists{/gist_id}","starred_url":"https://api.github.com/users/wardbell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wardbell/subscriptions","organizations_url":"https://api.github.com/users/wardbell/orgs","repos_url":"https://api.github.com/users/wardbell/repos","events_url":"https://api.github.com/users/wardbell/events{/privacy}","received_events_url":"https://api.github.com/users/wardbell/received_events","type":"User","site_admin":false},"body":"Actually, there are only two choices: \"they can be siblings or they can be in distant branches of the application component hierarchy.\"  All components have a common root ancestor ... unless you're thinking about two separate applications launched from the same index.html ... a scenario I think we can safely ignore.","created_at":"2015-12-30T00:52:57Z","updated_at":"2015-12-30T00:52:57Z","html_url":"https://github.com/angular/angular.io/pull/622#discussion_r48581614","pull_request_url":"https://api.github.com/repos/angular/angular.io/pulls/622","_links":{"self":{"href":"https://api.github.com/repos/angular/angular.io/pulls/comments/48581614"},"html":{"href":"https://github.com/angular/angular.io/pull/622#discussion_r48581614"},"pull_request":{"href":"https://api.github.com/repos/angular/angular.io/pulls/622"}}},"pull_request":{"url":"https://api.github.com/repos/angular/angular.io/pulls/622","id":54748724,"html_url":"https://github.com/angular/angular.io/pull/622","diff_url":"https://github.com/angular/angular.io/pull/622.diff","patch_url":"https://github.com/angular/angular.io/pull/622.patch","issue_url":"https://api.github.com/repos/angular/angular.io/issues/622","number":622,"state":"open","locked":false,"title":"[WIP] docs(component communication): new chapter","user":{"login":"wardbell","id":129061,"avatar_url":"https://avatars.githubusercontent.com/u/129061?v=3","gravatar_id":"","url":"https://api.github.com/users/wardbell","html_url":"https://github.com/wardbell","followers_url":"https://api.github.com/users/wardbell/followers","following_url":"https://api.github.com/users/wardbell/following{/other_user}","gists_url":"https://api.github.com/users/wardbell/gists{/gist_id}","starred_url":"https://api.github.com/users/wardbell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wardbell/subscriptions","organizations_url":"https://api.github.com/users/wardbell/orgs","repos_url":"https://api.github.com/users/wardbell/repos","events_url":"https://api.github.com/users/wardbell/events{/privacy}","received_events_url":"https://api.github.com/users/wardbell/received_events","type":"User","site_admin":false},"body":"WORK IN PROGRESS - do not merge\r\nNew chapter in review.\r\nReplaces #543","created_at":"2015-12-29T18:48:14Z","updated_at":"2015-12-30T00:52:57Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d72b33454e01f9fb1d0bdd685931d6a520379fe9","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/angular/angular.io/pulls/622/commits","review_comments_url":"https://api.github.com/repos/angular/angular.io/pulls/622/comments","review_comment_url":"https://api.github.com/repos/angular/angular.io/pulls/comments{/number}","comments_url":"https://api.github.com/repos/angular/angular.io/issues/622/comments","statuses_url":"https://api.github.com/repos/angular/angular.io/statuses/c2b8f95f36484baaebc4e374aed9618d4a85f8fa","head":{"label":"IdeaBlade:devguide-component-communication-new","ref":"devguide-component-communication-new","sha":"c2b8f95f36484baaebc4e374aed9618d4a85f8fa","user":{"login":"IdeaBlade","id":1630193,"avatar_url":"https://avatars.githubusercontent.com/u/1630193?v=3","gravatar_id":"","url":"https://api.github.com/users/IdeaBlade","html_url":"https://github.com/IdeaBlade","followers_url":"https://api.github.com/users/IdeaBlade/followers","following_url":"https://api.github.com/users/IdeaBlade/following{/other_user}","gists_url":"https://api.github.com/users/IdeaBlade/gists{/gist_id}","starred_url":"https://api.github.com/users/IdeaBlade/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/IdeaBlade/subscriptions","organizations_url":"https://api.github.com/users/IdeaBlade/orgs","repos_url":"https://api.github.com/users/IdeaBlade/repos","events_url":"https://api.github.com/users/IdeaBlade/events{/privacy}","received_events_url":"https://api.github.com/users/IdeaBlade/received_events","type":"Organization","site_admin":false},"repo":{"id":40154922,"name":"angular.io","full_name":"IdeaBlade/angular.io","owner":{"login":"IdeaBlade","id":1630193,"avatar_url":"https://avatars.githubusercontent.com/u/1630193?v=3","gravatar_id":"","url":"https://api.github.com/users/IdeaBlade","html_url":"https://github.com/IdeaBlade","followers_url":"https://api.github.com/users/IdeaBlade/followers","following_url":"https://api.github.com/users/IdeaBlade/following{/other_user}","gists_url":"https://api.github.com/users/IdeaBlade/gists{/gist_id}","starred_url":"https://api.github.com/users/IdeaBlade/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/IdeaBlade/subscriptions","organizations_url":"https://api.github.com/users/IdeaBlade/orgs","repos_url":"https://api.github.com/users/IdeaBlade/repos","events_url":"https://api.github.com/users/IdeaBlade/events{/privacy}","received_events_url":"https://api.github.com/users/IdeaBlade/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/IdeaBlade/angular.io","description":"Website for Angular 2","fork":true,"url":"https://api.github.com/repos/IdeaBlade/angular.io","forks_url":"https://api.github.com/repos/IdeaBlade/angular.io/forks","keys_url":"https://api.github.com/repos/IdeaBlade/angular.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/IdeaBlade/angular.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/IdeaBlade/angular.io/teams","hooks_url":"https://api.github.com/repos/IdeaBlade/angular.io/hooks","issue_events_url":"https://api.github.com/repos/IdeaBlade/angular.io/issues/events{/number}","events_url":"https://api.github.com/repos/IdeaBlade/angular.io/events","assignees_url":"https://api.github.com/repos/IdeaBlade/angular.io/assignees{/user}","branches_url":"https://api.github.com/repos/IdeaBlade/angular.io/branches{/branch}","tags_url":"https://api.github.com/repos/IdeaBlade/angular.io/tags","blobs_url":"https://api.github.com/repos/IdeaBlade/angular.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/IdeaBlade/angular.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/IdeaBlade/angular.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/IdeaBlade/angular.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/IdeaBlade/angular.io/statuses/{sha}","languages_url":"https://api.github.com/repos/IdeaBlade/angular.io/languages","stargazers_url":"https://api.github.com/repos/IdeaBlade/angular.io/stargazers","contributors_url":"https://api.github.com/repos/IdeaBlade/angular.io/contributors","subscribers_url":"https://api.github.com/repos/IdeaBlade/angular.io/subscribers","subscription_url":"https://api.github.com/repos/IdeaBlade/angular.io/subscription","commits_url":"https://api.github.com/repos/IdeaBlade/angular.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/IdeaBlade/angular.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/IdeaBlade/angular.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/IdeaBlade/angular.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/IdeaBlade/angular.io/contents/{+path}","compare_url":"https://api.github.com/repos/IdeaBlade/angular.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/IdeaBlade/angular.io/merges","archive_url":"https://api.github.com/repos/IdeaBlade/angular.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/IdeaBlade/angular.io/downloads","issues_url":"https://api.github.com/repos/IdeaBlade/angular.io/issues{/number}","pulls_url":"https://api.github.com/repos/IdeaBlade/angular.io/pulls{/number}","milestones_url":"https://api.github.com/repos/IdeaBlade/angular.io/milestones{/number}","notifications_url":"https://api.github.com/repos/IdeaBlade/angular.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/IdeaBlade/angular.io/labels{/name}","releases_url":"https://api.github.com/repos/IdeaBlade/angular.io/releases{/id}","created_at":"2015-08-04T00:40:19Z","updated_at":"2015-11-20T12:59:41Z","pushed_at":"2015-12-29T19:48:49Z","git_url":"git://github.com/IdeaBlade/angular.io.git","ssh_url":"git@github.com:IdeaBlade/angular.io.git","clone_url":"https://github.com/IdeaBlade/angular.io.git","svn_url":"https://github.com/IdeaBlade/angular.io","homepage":"https://angular.io","size":17227,"stargazers_count":2,"watchers_count":2,"language":"HTML","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":0,"forks":4,"open_issues":0,"watchers":2,"default_branch":"master"}},"base":{"label":"angular:master","ref":"master","sha":"95955e48e8430a599538fcae7f84d5bb4b9d3e14","user":{"login":"angular","id":139426,"avatar_url":"https://avatars.githubusercontent.com/u/139426?v=3","gravatar_id":"","url":"https://api.github.com/users/angular","html_url":"https://github.com/angular","followers_url":"https://api.github.com/users/angular/followers","following_url":"https://api.github.com/users/angular/following{/other_user}","gists_url":"https://api.github.com/users/angular/gists{/gist_id}","starred_url":"https://api.github.com/users/angular/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/angular/subscriptions","organizations_url":"https://api.github.com/users/angular/orgs","repos_url":"https://api.github.com/users/angular/repos","events_url":"https://api.github.com/users/angular/events{/privacy}","received_events_url":"https://api.github.com/users/angular/received_events","type":"Organization","site_admin":false},"repo":{"id":31985425,"name":"angular.io","full_name":"angular/angular.io","owner":{"login":"angular","id":139426,"avatar_url":"https://avatars.githubusercontent.com/u/139426?v=3","gravatar_id":"","url":"https://api.github.com/users/angular","html_url":"https://github.com/angular","followers_url":"https://api.github.com/users/angular/followers","following_url":"https://api.github.com/users/angular/following{/other_user}","gists_url":"https://api.github.com/users/angular/gists{/gist_id}","starred_url":"https://api.github.com/users/angular/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/angular/subscriptions","organizations_url":"https://api.github.com/users/angular/orgs","repos_url":"https://api.github.com/users/angular/repos","events_url":"https://api.github.com/users/angular/events{/privacy}","received_events_url":"https://api.github.com/users/angular/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/angular/angular.io","description":"Website for Angular 2","fork":false,"url":"https://api.github.com/repos/angular/angular.io","forks_url":"https://api.github.com/repos/angular/angular.io/forks","keys_url":"https://api.github.com/repos/angular/angular.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/angular/angular.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/angular/angular.io/teams","hooks_url":"https://api.github.com/repos/angular/angular.io/hooks","issue_events_url":"https://api.github.com/repos/angular/angular.io/issues/events{/number}","events_url":"https://api.github.com/repos/angular/angular.io/events","assignees_url":"https://api.github.com/repos/angular/angular.io/assignees{/user}","branches_url":"https://api.github.com/repos/angular/angular.io/branches{/branch}","tags_url":"https://api.github.com/repos/angular/angular.io/tags","blobs_url":"https://api.github.com/repos/angular/angular.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/angular/angular.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/angular/angular.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/angular/angular.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/angular/angular.io/statuses/{sha}","languages_url":"https://api.github.com/repos/angular/angular.io/languages","stargazers_url":"https://api.github.com/repos/angular/angular.io/stargazers","contributors_url":"https://api.github.com/repos/angular/angular.io/contributors","subscribers_url":"https://api.github.com/repos/angular/angular.io/subscribers","subscription_url":"https://api.github.com/repos/angular/angular.io/subscription","commits_url":"https://api.github.com/repos/angular/angular.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/angular/angular.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/angular/angular.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/angular/angular.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/angular/angular.io/contents/{+path}","compare_url":"https://api.github.com/repos/angular/angular.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/angular/angular.io/merges","archive_url":"https://api.github.com/repos/angular/angular.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/angular/angular.io/downloads","issues_url":"https://api.github.com/repos/angular/angular.io/issues{/number}","pulls_url":"https://api.github.com/repos/angular/angular.io/pulls{/number}","milestones_url":"https://api.github.com/repos/angular/angular.io/milestones{/number}","notifications_url":"https://api.github.com/repos/angular/angular.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/angular/angular.io/labels{/name}","releases_url":"https://api.github.com/repos/angular/angular.io/releases{/id}","created_at":"2015-03-10T22:32:34Z","updated_at":"2015-12-29T09:55:30Z","pushed_at":"2015-12-29T19:48:50Z","git_url":"git://github.com/angular/angular.io.git","ssh_url":"git@github.com:angular/angular.io.git","clone_url":"https://github.com/angular/angular.io.git","svn_url":"https://github.com/angular/angular.io","homepage":"https://angular.io","size":16745,"stargazers_count":174,"watchers_count":174,"language":"HTML","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":193,"mirror_url":null,"open_issues_count":105,"forks":193,"open_issues":105,"watchers":174,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/angular/angular.io/pulls/622"},"html":{"href":"https://github.com/angular/angular.io/pull/622"},"issue":{"href":"https://api.github.com/repos/angular/angular.io/issues/622"},"comments":{"href":"https://api.github.com/repos/angular/angular.io/issues/622/comments"},"review_comments":{"href":"https://api.github.com/repos/angular/angular.io/pulls/622/comments"},"review_comment":{"href":"https://api.github.com/repos/angular/angular.io/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/angular/angular.io/pulls/622/commits"},"statuses":{"href":"https://api.github.com/repos/angular/angular.io/statuses/c2b8f95f36484baaebc4e374aed9618d4a85f8fa"}}}}