@Output装饰器在Angular中是否严格只对click事件起作用?



我试图将数据从子组件传递到父组件,从子组件传递到父组件的变量值,不幸的是,父组件中没有进行任何更改。知道是怎么回事吗?或者@Output装饰器严格地只适用于子组件中的点击事件?我也会期望,它并不重要,如果我使用方法eventemitter或不,所以,例如设置emit为事件发射器内部构造函数或ngOnInit方法,我尝试了它,仍然不工作。

子组件:

import { Component, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'app-server',
templateUrl: './server.component.html',
styles: [
`.online {
color: white;
}

`
]
})
export class ServerComponent {
serverId: number = 10;
serverStatus: string = 'offline';
serverName: 'Random server';
@Output() serverNameEmitter = new EventEmitter<string>();
constructor() {
this.serverStatus = Math.random() > 0.5 ? 'online' : 'offline';
}
ngOnInit(): void {
this.passServerName(this.serverName);
}
passServerName(serverName: string) {
this.serverNameEmitter.emit(serverName);
}

getColor() {
return this.serverStatus == 'online' ? 'green' : 'red';
}
getServerStatus() {
return this.serverStatus;
}

}
父组件

import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-servers',
templateUrl: './servers.component.html',
styleUrls: ['./servers.component.css'],
})
export class ServersComponent implements OnInit {
allowNewServer = false;
serverCreationStatus = 'No server was created!';
serverNames = "";
serverStatus = false;
servers = [];
serverName = {
name: "Test server"
};

constructor() {
setTimeout(() => {
this.allowNewServer = true;
}, 2000);
}
ngOnInit(): void {}
onCreateServer() {
this.serverStatus = true;
this.servers.push(this.serverName.name);
this.serverCreationStatus = 'Server has been created! Name is ' + this.serverName.name;
}
onUpdateServerName(event: Event) {
this.serverNames = (event.target as HTMLInputElement).value;
}
changeServerName() {
this.serverName.name = this.serverNames;
}
gettingServerName(serverName: string) {
this.serverNames = serverName;
}
}

父组件HTML

<label>Server Name</label>
<input type="text" class="form-control" (input)="onUpdateServerName($event)">
<!--<input type="text" class="form-control" [(ngModel)]="serverName.name">-->
<!--<p>{{serverName}}</p>-->
<button class="btn btn-primary" [disabled]="!allowNewServer" 
(click)="onCreateServer()">Add Server</button>
<!--<p [innerText]="allowNewServer"></p>-->
<!--<p>{{serverCreationStatus}}</p>-->
<p>Here's {{ serverNames }}</p>
<p *ngIf="serverStatus; else noServer">Server was created, server name is {{ 
serverName.name }}</p>
<ng-template #noServer>
<p>No server was created!</p>
</ng-template>
<button class="btn btn-primary" (click)="changeServerName()">Change server name</button>
<app-server *ngFor="let server of servers" 
(serverNameEmitter)="gettingServerName($event)"></app-server>

您可以在每次调用gettingServerName()时手动触发变更检测。这样你就可以避免Flo提到的ExpressionChangedAfterItHasBeenCheckedError。不需要使用timeout.

导入ChangeDetectorRef:

import { ChangeDetectorRef } from '@angular/core';

通过构造函数注入它,然后在gettingServerName()方法的末尾调用detectChanges():

constructor(private cdRef: ChangeDetectorRef) {}
gettingServerName(serverName: string) {
this.serverNames = serverName;
this.cdRef.detectChanges();
}

虽然我想补充:你并没有真正使用@Output的方式。

好的,我已经用你的代码创建了一个Stackblitz项目。但是我不明白....在父组件中设置新的服务器名称。然后可以添加一个新服务器。但是,如果创建了子节点,则不会为它设置名称。所以子进程发出事件(它可以工作)然后将serverNames设置为随机服务器;总是这样。

我唯一看到的是:你得到了一个ExpressionChangedAfterItHasBeenCheckedError如果你在onInit()的子线程中发出了serverName。简单技巧:setTimeout.

但是看看Stackblitz和玩它。如果你有其他问题,请告诉我。

问候,弗洛

相关内容

  • 没有找到相关文章

最新更新