5 lines
20 KiB
JSON
5 lines
20 KiB
JSON
{
|
|
"id": "guide/inputs-outputs",
|
|
"title": "Sharing data between child and parent directives and components",
|
|
"contents": "\n\n\n<div class=\"github-links\">\n <a href=\"https://github.com/angular/angular/edit/master/aio/content/guide/inputs-outputs.md?message=docs%3A%20describe%20your%20change...\" aria-label=\"Suggest Edits\" title=\"Suggest Edits\"><i class=\"material-icons\" aria-hidden=\"true\" role=\"img\">mode_edit</i></a>\n</div>\n\n\n<div class=\"content\">\n <h1 id=\"sharing-data-between-child-and-parent-directives-and-components\">Sharing data between child and parent directives and components<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/inputs-outputs#sharing-data-between-child-and-parent-directives-and-components\"><i class=\"material-icons\">link</i></a></h1>\n<p>A common pattern in Angular is sharing data between a parent component and one or more child components.\nYou can implement this pattern by using the <code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code> and <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code> directives.</p>\n<div class=\"alert is-helpful\">\n<p>See the <live-example></live-example> for a working example containing the code snippets in this guide.</p>\n</div>\n<p>Consider the following hierarchy:</p>\n<code-example language=\"html\">\n<parent-component>\n <child-component></child-component>\n</parent-component>\n</code-example>\n<p>The <code><parent-component></code> serves as the context for the <code><child-component></code>.</p>\n<p><code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code> and <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code> give a child component a way to communicate with its parent component.\n<code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code> allows a parent component to update data in the child component.\nConversely, <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code> allows the child to send data to a parent component.</p>\n<a id=\"input\"></a>\n<h2 id=\"sending-data-to-a-child-component\">Sending data to a child component<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/inputs-outputs#sending-data-to-a-child-component\"><i class=\"material-icons\">link</i></a></h2>\n<p>The <code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code> decorator in a child component or directive signifies that the property can receive its value from its parent component.</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/inputs-outputs/input.svg\" alt=\"Input data flow diagram\" width=\"671\" height=\"346\">\n</div>\n<p>To use <code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code>, you must configure the parent and child.</p>\n<h3 id=\"configuring-the-child-component\">Configuring the child component<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/inputs-outputs#configuring-the-child-component\"><i class=\"material-icons\">link</i></a></h3>\n<p>To use the <code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code> decorator in a child component class, first import <code><a href=\"api/core/Input\" class=\"code-anchor\">Input</a></code> and then decorate the property with <code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code>, as in the following example.</p>\n<code-example path=\"inputs-outputs/src/app/item-detail/item-detail.component.ts\" region=\"use-input\" header=\"src/app/item-detail/item-detail.component.ts\">\nimport { <a href=\"api/core/Component\" class=\"code-anchor\">Component</a>, <a href=\"api/core/Input\" class=\"code-anchor\">Input</a> } from '@angular/core'; // First, import <a href=\"api/core/Input\" class=\"code-anchor\">Input</a>\nexport class ItemDetailComponent {\n @<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>() item: string; // decorate the property with @<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()\n}\n\n</code-example>\n<p>In this case, <code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code> decorates the property <code class=\"no-auto-link\">item</code>, which has a type of <code>string</code>, however, <code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code> properties can have any type, such as <code><a href=\"api/common/DecimalPipe\" class=\"code-anchor\">number</a></code>, <code>string</code>, <code>boolean</code>, or <code>object</code>.\nThe value for <code>item</code> comes from the parent component.</p>\n<p>Next, in the child component template, add the following:</p>\n<code-example path=\"inputs-outputs/src/app/item-detail/item-detail.component.html\" region=\"property-in-template\" header=\"src/app/item-detail/item-detail.component.html\">\n<p>\n Today's item: {{item}}\n</p>\n\n</code-example>\n<h3 id=\"configuring-the-parent-component\">Configuring the parent component<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/inputs-outputs#configuring-the-parent-component\"><i class=\"material-icons\">link</i></a></h3>\n<p>The next step is to bind the property in the parent component's template.\nIn this example, the parent component template is <code>app.component.html</code>.</p>\n<ol>\n<li>\n<p>Use the child's selector, here <code><app-item-detail></code>, as a directive within the\nparent component template.</p>\n</li>\n<li>\n<p>Use <a href=\"guide/property-binding\">property binding</a> to bind the <code>item</code> property in the child to the <code>currentItem</code> property of the parent.</p>\n</li>\n</ol>\n<code-example path=\"inputs-outputs/src/app/app.component.html\" region=\"input-parent\" header=\"src/app/app.component.html\">\n<app-item-detail [item]=\"currentItem\"></app-item-detail>\n\n</code-example>\n<ol start=\"3\">\n<li>In the parent component class, designate a value for <code>currentItem</code>:</li>\n</ol>\n<code-example path=\"inputs-outputs/src/app/app.component.ts\" region=\"parent-property\" header=\"src/app/app.component.ts\">\nexport class AppComponent {\n currentItem = 'Television';\n}\n\n</code-example>\n<p>With <code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code>, Angular passes the value for <code>currentItem</code> to the child so that <code>item</code> renders as <code>Television</code>.</p>\n<p>The following diagram shows this structure:</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/inputs-outputs/input-diagram-target-source.svg\" alt=\"Property binding diagram\" width=\"502\" height=\"304\">\n</div>\n<p>The target in the square brackets, <code>[]</code>, is the property you decorate with <code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code> in the child component.\nThe binding source, the part to the right of the equal sign, is the data that the parent component passes to the nested component.</p>\n<h3 id=\"watching-for-input-changes\">Watching for <code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code> changes<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/inputs-outputs#watching-for-input-changes\"><i class=\"material-icons\">link</i></a></h3>\n<p>To watch for changes on an <code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code> property, you can use <code><a href=\"api/core/OnChanges\" class=\"code-anchor\">OnChanges</a></code>, one of Angular's <a href=\"guide/lifecycle-hooks\">lifecycle hooks</a>.\nSee the <a href=\"guide/lifecycle-hooks#onchanges\"><code>OnChanges</code></a> section of the <a href=\"guide/lifecycle-hooks\">Lifecycle Hooks</a> guide for more details and examples.</p>\n<a id=\"output\"></a>\n<h2 id=\"sending-data-to-a-parent-component\">Sending data to a parent component<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/inputs-outputs#sending-data-to-a-parent-component\"><i class=\"material-icons\">link</i></a></h2>\n<p>The <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code> decorator in a child component or directive allows data to flow from the child to the parent.</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/inputs-outputs/output.svg\" alt=\"Output diagram\" width=\"666\" height=\"340\">\n</div>\n<p><code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code> marks a property in a child component as a doorway through which data can travel from the child to the parent.</p>\n<p>The child component uses the <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code> property to raise an event to notify the parent of the change.\nTo raise an event, an <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code> must have the type of <code><a href=\"api/core/EventEmitter\" class=\"code-anchor\">EventEmitter</a></code>, which is a class in <code>@angular/core</code> that you use to emit custom events.</p>\n<p>The following example shows how to set up an <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code> in a child component that pushes data from an HTML <code><input></code> to an array in the parent component.</p>\n<p>To use <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code>, you must configure the parent and child.</p>\n<h3 id=\"configuring-the-child-component-1\">Configuring the child component<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/inputs-outputs#configuring-the-child-component-1\"><i class=\"material-icons\">link</i></a></h3>\n<p>The following example features an <code><input></code> where a user can enter a value and click a <code><button></code> that raises an event. The <code><a href=\"api/core/EventEmitter\" class=\"code-anchor\">EventEmitter</a></code> then relays the data to the parent component.</p>\n<ol>\n<li>\n<p>Import <code><a href=\"api/core/Output\" class=\"code-anchor\">Output</a></code> and <code><a href=\"api/core/EventEmitter\" class=\"code-anchor\">EventEmitter</a></code> in the child component class:</p>\n<code-example language=\"js\">\nimport { <a href=\"api/core/Output\" class=\"code-anchor\">Output</a>, <a href=\"api/core/EventEmitter\" class=\"code-anchor\">EventEmitter</a> } from '@angular/core';\n</code-example>\n</li>\n<li>\n<p>In the component class, decorate a property with <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code>.\nThe following example <code>newItemEvent</code> <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code> has a type of <code><a href=\"api/core/EventEmitter\" class=\"code-anchor\">EventEmitter</a></code>, which means it's an event.</p>\n<code-example path=\"inputs-outputs/src/app/item-output/item-output.component.ts\" region=\"item-output\" header=\"src/app/item-output/item-output.component.ts\">\n\n@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>() newItemEvent = new <a href=\"api/core/EventEmitter\" class=\"code-anchor\">EventEmitter</a><string>();\n\n\n</code-example>\n<p>The different parts of the above declaration are as follows:</p>\n<ul>\n<li><code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code>—a decorator function marking the property as a way for data to go from the child to the parent</li>\n<li><code>newItemEvent</code>—the name of the <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code></li>\n<li><code><a href=\"api/core/EventEmitter\" class=\"code-anchor\">EventEmitter</a><string></code>—the <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code>'s type</li>\n<li><code>new <a href=\"api/core/EventEmitter\" class=\"code-anchor\">EventEmitter</a><string>()</code>—tells Angular to create a new event emitter and that the data it emits is of type string.</li>\n</ul>\n<p>For more information on <code><a href=\"api/core/EventEmitter\" class=\"code-anchor\">EventEmitter</a></code>, see the <a href=\"api/core/EventEmitter\">EventEmitter API documentation</a>.</p>\n</li>\n<li>\n<p>Create an <code>addNewItem()</code> method in the same component class:</p>\n<code-example path=\"inputs-outputs/src/app/item-output/item-output.component.ts\" region=\"item-output-class\" header=\"src/app/item-output/item-output.component.ts\">\nexport class ItemOutputComponent {\n\n @<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>() newItemEvent = new <a href=\"api/core/EventEmitter\" class=\"code-anchor\">EventEmitter</a><string>();\n\n addNewItem(value: string) {\n this.newItemEvent.emit(value);\n }\n}\n\n</code-example>\n<p>The <code>addNewItem()</code> function uses the <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code>, <code>newItemEvent</code>, to raise an event with the value the user types into the <code><input></code>.</p>\n</li>\n</ol>\n<h3 id=\"configuring-the-childs-template\">Configuring the child's template<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/inputs-outputs#configuring-the-childs-template\"><i class=\"material-icons\">link</i></a></h3>\n<p>The child's template has two controls.\nThe first is an HTML <code><input></code> with a <a href=\"guide/template-reference-variables\">template reference variable</a> , <code>#newItem</code>, where the user types in an item name.\nThe <code>value</code> property of the <code>#newItem</code> variable stores what the user types into the <code><input></code>.</p>\n<code-example path=\"inputs-outputs/src/app/item-output/item-output.component.html\" region=\"child-output\" header=\"src/app/item-output/item-output.component.html\">\n<label>Add an item: <input #newItem></label>\n<button (click)=\"addNewItem(newItem.value)\">Add to parent's list</button>\n\n</code-example>\n<p>The second element is a <code><button></code> with a <code>click</code> <a href=\"guide/event-binding\">event binding</a>.</p>\n<p>The <code>(click)</code> event is bound to the <code>addNewItem()</code> method in the child component class.\nThe <code>addNewItem()</code> method takes as its argument the value of the <code>#newItem.value</code> property.</p>\n<h3 id=\"configuring-the-parent-component-1\">Configuring the parent component<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/inputs-outputs#configuring-the-parent-component-1\"><i class=\"material-icons\">link</i></a></h3>\n<p>The <code>AppComponent</code> in this example features a list of <code>items</code> in an array and a method for adding more items to the array.</p>\n<code-example path=\"inputs-outputs/src/app/app.component.ts\" region=\"add-new-item\" header=\"src/app/app.component.ts\">\nexport class AppComponent {\n items = ['item1', 'item2', 'item3', 'item4'];\n\n addItem(newItem: string) {\n this.items.push(newItem);\n }\n}\n\n</code-example>\n<p>The <code>addItem()</code> method takes an argument in the form of a string and then adds that string to the <code>items</code> array.</p>\n<h3 id=\"configuring-the-parents-template\">Configuring the parent's template<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/inputs-outputs#configuring-the-parents-template\"><i class=\"material-icons\">link</i></a></h3>\n<ol>\n<li>\n<p>In the parent's template, bind the parent's method to the child's event.</p>\n</li>\n<li>\n<p>Put the child selector, here <code><app-item-output></code>, within the parent component's template, <code>app.component.html</code>.</p>\n<code-example path=\"inputs-outputs/src/app/app.component.html\" region=\"output-parent\" header=\"src/app/app.component.html\">\n<app-item-output (newItemEvent)=\"addItem($event)\"></app-item-output>\n\n</code-example>\n<p>The event binding, <code>(newItemEvent)='addItem($event)'</code>, connects the event in the child, <code>newItemEvent</code>, to the method in the parent, <code>addItem()</code>.</p>\n<p>The <code>$event</code> contains the data that the user types into the <code><input></code> in the child template UI.</p>\n<p>To see the <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code> working, you can add the following to the parent's template:</p>\n<code-example language=\"html\">\n <ul>\n <li *<a href=\"api/common/NgForOf\" class=\"code-anchor\">ngFor</a>=\"let item of items\">{{item}}</li>\n </ul>\n</code-example>\n<p>The <code>*<a href=\"api/common/NgForOf\" class=\"code-anchor\">ngFor</a></code> iterates over the items in the <code>items</code> array.\nWhen you enter a value in the child's <code><input></code> and click the button, the child emits the event and the parent's <code>addItem()</code> method pushes the value to the <code>items</code> array and new item renders in the list.</p>\n</li>\n</ol>\n<h2 id=\"using-input-and-output-together\">Using <code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code> and <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code> together<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/inputs-outputs#using-input-and-output-together\"><i class=\"material-icons\">link</i></a></h2>\n<p>You can use <code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code> and <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code> on the same child component as follows:</p>\n<code-example path=\"inputs-outputs/src/app/app.component.html\" region=\"together\" header=\"src/app/app.component.html\">\n<app-input-output [item]=\"currentItem\" (deleteRequest)=\"crossOffItem($event)\"></app-input-output>\n\n</code-example>\n<p>The target, <code>item</code>, which is an <code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code> property in the child component class, receives its value from the parent's property, <code>currentItem</code>.\nWhen you click delete, the child component raises an event, <code>deleteRequest</code>, which is the argument for the parent's <code>crossOffItem()</code> method.</p>\n<p>The following diagram shows the different parts of the <code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code> and <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code> on the <code><app-input-output></code> child component.</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/inputs-outputs/input-output-diagram.svg\" alt=\"Input/Output diagram\" width=\"800\" height=\"333\">\n</div>\n<p>The child selector is <code><app-input-output></code> with <code>item</code> and <code>deleteRequest</code> being <code>@<a href=\"api/core/Input\" class=\"code-anchor\">Input</a>()</code> and <code>@<a href=\"api/core/Output\" class=\"code-anchor\">Output</a>()</code>\nproperties in the child component class.\nThe property <code>currentItem</code> and the method <code>crossOffItem()</code> are both in the parent component class.</p>\n<p>To combine property and event bindings using the banana-in-a-box\nsyntax, <code>[()]</code>, see <a href=\"guide/two-way-binding\">Two-way Binding</a>.</p>\n\n \n</div>\n\n<!-- links to this doc:\n - api/core/Input\n - api/core/Output\n - guide/built-in-directives\n - guide/component-interaction\n - guide/example-apps-list\n - guide/glossary\n - guide/observables-in-angular\n - guide/template-syntax\n - guide/two-way-binding\n - tutorial/toh-pt3\n-->\n<!-- links from this doc:\n - api/common/DecimalPipe\n - api/common/NgForOf\n - api/core/Component\n - api/core/EventEmitter\n - api/core/Input\n - api/core/OnChanges\n - api/core/Output\n - guide/event-binding\n - guide/inputs-outputs#configuring-the-child-component\n - guide/inputs-outputs#configuring-the-child-component-1\n - guide/inputs-outputs#configuring-the-childs-template\n - guide/inputs-outputs#configuring-the-parent-component\n - guide/inputs-outputs#configuring-the-parent-component-1\n - guide/inputs-outputs#configuring-the-parents-template\n - guide/inputs-outputs#sending-data-to-a-child-component\n - guide/inputs-outputs#sending-data-to-a-parent-component\n - guide/inputs-outputs#sharing-data-between-child-and-parent-directives-and-components\n - guide/inputs-outputs#using-input-and-output-together\n - guide/inputs-outputs#watching-for-input-changes\n - guide/lifecycle-hooks\n - guide/lifecycle-hooks#onchanges\n - guide/property-binding\n - guide/template-reference-variables\n - guide/two-way-binding\n - https://github.com/angular/angular/edit/master/aio/content/guide/inputs-outputs.md?message=docs%3A%20describe%20your%20change...\n-->"
|
|
} |