我是 Angular 2 的绝对初学者,我对我正在研究的关于“绑定(bind)到自定义事件”的教程示例有一些疑问。
所以我有一个主要组件,该组件的 View 名为app.component.html:
<div class="container">
<app-cockpit
(serverCreated)="onServerAdded($event)"
(blueprintCreated)="onBlueprintAdded($event)">
</app-cockpit>
<hr>
<div class="row">
<div class="col-xs-12">
<app-server-element
*ngFor="let serverElement of serverElements"
[srvElement]="serverElement"></app-server-element>
</div>
</div>
</div>
在此 View 中定义了子组件的包含,该子组件在上一个主视图中包含此 subview ,cockpit.component.html文件内容:
<div class="row">
<div class="col-xs-12">
<p>Add new Servers or blueprints!</p>
<label>Server Name</label>
<input type="text" class="form-control" [(ngModel)]="newServerName">
<label>Server Content</label>
<input type="text" class="form-control" [(ngModel)]="newServerContent">
<br>
<button
class="btn btn-primary"
(click)="onAddServer()">Add Server</button>
<button
class="btn btn-primary"
(click)="onAddBlueprint()">Add Server Blueprint</button>
</div>
</div>
其中包含 2 个用于提交表单的按钮。
这是第一个疑问,根据我的理解,做类似的事情:
(click)="onAddServer()
意思是这样的:“当点击事件发生时,执行定义到该 View 的 Controller 中的onAddServer()方法”。
所以,进入我的 coockpit.component.ts 类:
import {Component, EventEmitter, OnInit, Output} from '@angular/core';
@Component({
selector: 'app-cockpit',
templateUrl: './cockpit.component.html',
styleUrls: ['./cockpit.component.css']
})
export class CockpitComponent implements OnInit {
/*
EvebtEmitter è un oggetto del framework Angular che permette di emettere i nostri custom events
@Output() decorator usato per passare qualcosa fuori dal component
*/
@Output() serverCreated = new EventEmitter<{serverName: string, serverContent: string}>();
@Output() blueprintCreated = new EventEmitter<{serverName: string, serverContent: string}>();
newServerName = '';
newServerContent = '';
constructor() { }
ngOnInit() {
}
onAddServer() {
this.serverCreated.emit({serverName: this.newServerName, serverContent: this.newServerContent});
}
onAddBlueprint() {
console.log('INTO onAddBluePrint()');
this.blueprintCreated.emit({serverName: this.newServerName, serverContent: this.newServerContent});
}
}
应该以这种方式工作:
newServerName 和 newServerContent 变量包含用户在表单中插入的数据,因为这些变量由 [(ngModel)] 绑定(bind)指令:
<input type="text" class="form-control" [(ngModel)]="newServerName">
<input type="text" class="form-control" [(ngModel)]="newServerContent">
当用户单击添加服务器按钮时,将执行onAddServer()方法,并生成一个带有serverName和serverContent的事件 内容在外部发出:
this.serverCreated.emit({serverName: this.newServerName, serverContent: this.newServerContent});
所以一个疑问是:事件到底是什么?在我看来,这是一个包含一些信息的简单 Json 对象。
那么第二个疑问是:serverCreated事件是由这个 Controller 发送给外部的,因为它是使用@Output()装饰器来修饰的。
默认收件人是什么?在我看来,这是父组件的 Controller ,因为在我的 app.component.ts 类中,我有这个方法来处理此事件:
onServerAdded(serverData: {serverName: string, serverContent: string}) { this.serverElements.push({ 类型:'服务器', 名称:服务器数据.服务器名称, 内容:serverData.serverContent }); }
确切的意思是:
这就像我在说,从主组件的 Angular 来看,我是在说 app-cockpit 组件将这些事件扔给父组件。
我的推理正确还是我遗漏了什么?所以这意味着我只能使用这个策略将事件从子组件传递到父组件或者我可以做相反的事情(从父组件到子组件,我不知道这是否是一个真实的用例场景)。
最佳答案
你的推理基本上是正确的。
专门针对您的疑问:
1) 当您发出事件时,例如在您的情况下通过 this.serverCreated.emit()
方法调用,您可以作为 emit()
的参数传递code> method 任何对象,因此也是一个纯 javascript Json 对象。您可以传递您可以定义为 Typescript 类实例的任何其他对象以及任何基本类型(例如字符串或数字)
2) 使用 @Output() 装饰器定义的事件可以被父组件监听,因此被用作允许子组件与其父组件对话的机制。父组件可以通过对称的@Input()机制将参数传递给子组件。
您可以在 https://angular.io/guide/component-interaction 获取组件之间相互通信的方法的完整列表。
关于javascript - 这个有关自定义事件绑定(bind)的 Angular 2 教程究竟如何运作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44545419/