[英]Angular: how to send data from child component to parent component?
我正在學習 Angular。 我已經閱讀了文檔和五篇博文,一切都一清二楚。 我認為有兩個模板。 子模板有一個按鈕。 當用戶單擊按鈕時,我希望在父模板中顯示一個元素(說明卡)。 當用戶再次單擊按鈕時,我希望該元素不顯示。 即,子按鈕打開和關閉父元素。
<button (click)="toggleInstructions()">Instructions</button>
在我的頭(子)組件中,我制作了一個輸出事件發射器sendData
、一個布爾變量showInstructions
和一個在true
和false
之間切換showInstructions
的函數。 在記錄showInstructions
(效果很好!)之后,它會調用sendData
來發出數據。 我創建了一個新變量myData
因為我對this
的使用感到困惑。
import { Component, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent {
@Output() sendData = new EventEmitter<boolean>();
showInstructions: boolean = false;
toggleInstructions(myData: boolean) {
console.log("Clicked!");
switch (true) {
case (this.showInstructions === true):
this.showInstructions = false;
break;
case (this.showInstructions === false):
this.showInstructions = true;
break;
default:
console.log("Error in switch-case.");
}
console.log(this.showInstructions);
myData = this.showInstructions;
console.log(myData);
this.sendData.emit(myData);
}
}
在父組件中,我導入了子組件( HeaderComponent
)並創建了一個函數toggledInstructions
來接收數據。 當我單擊按鈕時,沒有記錄任何內容。
import { Component } from '@angular/core';
import { HeaderComponent } from './header/header.component';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
toggledInstructions(myData: boolean) {
console.log("Data coming in!");
console.log(myData);
}
}
我很困惑這應該如何工作。 除了數據變量名稱( myData
)之外,我在連接發送和接收函數的文檔中看不到任何內容。
謝謝你的幫助!
我發現這個 ZeroesAndOnes 博客文章很好地解釋了這一點。 要解決我的答案,請從博客文章開始並啟動其代碼。
將child.component.html
更改為:
<div style="border: solid 1px gray; padding: 15px; margin-top: 15px;">
<h2>Child Component</h2>
<button (click)="clickButton()">Show Element in Parent</button>
</div>
子模板沒有什么特別之處。 只是一個觸發控制器功能的按鈕。
將child.component.ts
更改為:
import { Component, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
})
export class ChildComponent {
showElement: boolean = false;
@Output() buttonClicked: EventEmitter<boolean> = new EventEmitter<boolean>();
clickButton() {
console.log("(Child) Value before toggle: " + this.showElement);
console.log("(Child) Button clicked!");
switch (true) {
case (this.showElement === true):
this.showElement = false;
break;
case (this.showElement === false):
this.showElement = true;
break;
default:
console.log("Error in switch-case.");
}
console.log("(Child) Value after toggle: " + this.showElement);
this.buttonClicked.emit(this.showElement);
}
}
變量列表以showElement
開頭,它是一個boolean
並被初始化為false
,即父元素是隱藏的。
接下來是另一個變量,它是 Angular 魔法的第一位。 變量是buttonClicked
並且它有裝飾器@Output()
。 這個裝飾器意味着該變量將在控制器之外可用。 該變量的類型為EventEmitter<boolean>
並且它被分配了一個新的事件發射器。 如果您喜歡較短的行,則可以省略該類型:
@Output() buttonClicked = new EventEmitter<boolean>();
接下來是在true
和false
之間切換showElement
的函數。 在這個函數的底部是 Angular 魔法的第二位。 調用輸出事件並發送showElement
變量以由事件發射器發射。
現在將父模板app.component.html
更改為:
<div style="border: solid 1px gray; padding: 15px;">
<app-child (buttonClicked)="parentEventHandlerFunction($event)">
</app-child>
<h1>Parent Component</h1>
<span><b>Value emitted from child component is:</b></span>
{{ valueEmittedFromChildComponent }}
<div *ngIf="valueEmittedFromChildComponent"><span style="color: red;"><b>My awesome element!</b></span>
</div>
</div>
Angular 的大魔法在父模板中,特別是在這一行中:
<app-child (buttonClicked)="parentEventHandlerFunction($event)">
</app-child>
指令app-child
將子模板嵌入到父模板中。 buttonClicked
是子控制器中的事件發射器。 parentEventHandlerFunction
是父控制器中的一個函數。 $event
是從孩子發送給父母的對象。 這一行將子控制器和父控制器的部分組合在一起,用等號將它們連接起來。 這就是 Angular 的巨大魔力。
現在設置父控制器app.component.ts
:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent {
valueEmittedFromChildComponent: boolean;
parentEventHandlerFunction(valueEmitted){
this.valueEmittedFromChildComponent = valueEmitted;
console.log("(Parent) Value emitted: " + valueEmitted);
}
}
我們有一個名為valueEmittedFromChildComponent
變量,它是一個boolean
。 然后我們有一個函數parentEventHandlerFunction
和一個參數valueEmitted
。 $event
對象來自父模板中的魔法線,並分配給局部變量valueEmittedFromChildComponent
。
回到父模板,我們顯示局部變量valueEmittedFromChildComponent
並在*ngIf
使用它來顯示和隱藏元素。
ZeroesAndOne 總結了他們的博客文章,“總而言之,Angular 可以非常輕松地創建使用 @Output() 裝飾器向其父組件發送數據的子組件。” 哈! 這不是我所說的“極其容易”。 相比之下,在 AngularJS 中,兩個模板將共享一個控制器。 一個模板中的按鈕綁定到控制器中的一個函數,該函數切換一個變量,該變量綁定到第二個模板中的元素以顯示和隱藏元素。 數據從第一個模板到控制器中的單個變量再到第二個模板。 這“非常容易”。
在 Angular 中,子模板中的按鈕會觸發子控制器中的一個函數,與 AngularJS 相同。 但是隨后您需要使用事件發射器制作一個@Output()
裝飾器,並從切換函數中調用事件發射器。 然后數據被發送到父模板中的魔術線,它結合了來自子控制器和父控制器的東西。 然后數據進入父控制器,然后返回父模板以顯示或隱藏目標元素。
讓我們重復一遍。 當用戶單擊子模板中的按鈕時,數據進入子控制器,在那里函數切換值,然后將數據從函數發送到事件發射器。 事件發射器將數據發送到父模板,父模板將數據發送到父控制器,父控制器將數據發送回父模板以顯示或隱藏元素。 這不是我所說的容易。
你會如何在 React 中做到這一點? React 更像 AngularJS 還是 Angular?
看起來您需要$event
變量來獲取發出的值:
<button (click)="toggleInstructions($event)">Instructions</button>
和
toggledInstructions(event: boolean) {
console.log("Data coming in!", myData);
}
事件綁定(fooevent)
允許綁定到 DOM 事件和EventEmitter
事件
更新:
工作代碼示例:
ChildComponent.ts:
@Output() public onFooClicked = new EventEmitter<boolean>();
showMenu() {
this.onFooClicked .emit(true);
}
app.component.ts:
<foo (onFooClicked)="onClicked($event)">
</foo>
onClicked(event: boolean) {
console.log(`Somebody clicked`, event);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.