有没有办法从 Angular 中的组件内部检查 @Output 连接?
Is there a way to check for @Output wire up from within a component in Angular?
在组件的 ngOnInit
方法中,@Input
值将被绑定,因此您可以检查组件上的那些属性,但似乎没有办法检查 @Output
事件绑定。我想知道 @Output
是否连接到组件上。
(使用 Angular 和 TypeScript)
import {Component, Output, EventEmitter} from '@angular/core';
@Component({
selector: 'sample',
template: `<p>a sample</p>`
})
export class SampleComponent {
@Output() cancel = new EventEmitter();
ngOnInit() {
// would like to check and see if cancel was used
// on the element <sample (cancel)="doSomething()"></sample>
// or not <sample></sample>
}
}
以下代码应该有效:
import {Component, Output, EventEmitter, OnInit} from 'angular2/core';
import {ObservableWrapper} from 'angular2/src/facade/async';
@Component({
selector: 'sample',
template: `<p>a sample</p>`
})
export class SampleComponent implements OnInit {
@Output() cancel: EventEmitter<any> = new EventEmitter();
private isCancelUsed: boolean;
ngOnInit(): void {
this.isCancelUsed = ObservableWrapper.hasSubscribers(this.cancel);
}
}
与 user1448982 相同的方法,但不使用 ObservableWrapper
,这意味着平台代码不会通过 api.
公开使用。
(使用 Angular 2 RC1 和 TypeScript)
注意:这只从 2.0.0-beta.16 和更高版本开始工作
import {Component, Output, EventEmitter} from '@angular/core';
@Component({
selector: 'sample',
template: `<p>a sample</p>`
})
export class SampleComponent {
@Output() cancel = new EventEmitter();
private isCancelUsed = false;
ngOnInit() {
this.isCancelUsed = this.cancel.observers.length > 0;
}
}
ObservableWrapper.hasSubscribers
方法在内部执行此行,因此您可以在此处执行相同的操作。
使用 TypeScript 时,如果 Angular 最终将 EventEmitter
从 Subject
更改为 [=16= =], 因此 .observers
属性).
更新 (03 / 2022)
observers
属性自 rxjs v7 起已弃用。您现在可以使用一个布尔值来指示主题是否正在使用,而不是检查观察者数组的长度。
// Old approach
this.isCancelUsed = this.cancel.observers.length > 0;
// New approach
this.isCancelUsed = this.cancel.observed;
Angular 12 删除了 EventEmitter#observables
字段,因此接受的答案不再有效。
现在的替代解决方案是转换为 Subject:
get hasOutputEventSubscriber() {
return (this.cancel as Subject).observers;
}
请注意,此 属性 也已弃用,将在 rxjs v8 中删除。一个面向未来的解决方案是为 EventEmitter 编写自定义包装器 class。
这是一个不依赖于 Angular 或 rxjs 的任何内部结构的未来证明示例。这是一个围绕 EventEmitter
的简单包装器,它公开了一个 subscriberCount
属性,当订阅者是 added/removed.
时,它会自动 incremented/decremented
class WatchedEventEmitter extends EventEmitter<any> {
private _subscriberCount = 0;
get subscriberCount(): number {
return this._subscriberCount;
}
subscribe(next?: (value: any) => void, error?: (error: any) => void, complete?: () => void): Subscription {
++this._subscriberCount;
return super.subscribe(next, error, complete);
}
unsubscribe() {
--this._subscriberCount;
super.unsubscribe();
}
}
用法示例:
@Component({template: `
{{click.subscriberCount|json}}
<span *ngIf="cancel.subscriberCount">
<button mat-icon-button (click)="cancel.emit()">Click Me</button>
</span>
<span *ngIf="!cancel.subscriberCount">No Subscribers</span>
`})
export class SomeComponent {
@Output() cancel = new WatchedEventEmitter();
}
当前版本 Angular 13 检查是否有任何 observer/callback 提供你可以使用 this.cancel.observed
它将 return boolean
import {Component, Output, EventEmitter} from '@angular/core';
@Component({
selector: 'sample',
template: `<p>a sample</p>`
})
export class SampleComponent {
@Output() cancel = new EventEmitter();
private isCancelUsed = false;
ngOnInit() {
this.isCancelUsed = this.cancel.observed;
}
}
在组件的 ngOnInit
方法中,@Input
值将被绑定,因此您可以检查组件上的那些属性,但似乎没有办法检查 @Output
事件绑定。我想知道 @Output
是否连接到组件上。
(使用 Angular 和 TypeScript)
import {Component, Output, EventEmitter} from '@angular/core';
@Component({
selector: 'sample',
template: `<p>a sample</p>`
})
export class SampleComponent {
@Output() cancel = new EventEmitter();
ngOnInit() {
// would like to check and see if cancel was used
// on the element <sample (cancel)="doSomething()"></sample>
// or not <sample></sample>
}
}
以下代码应该有效:
import {Component, Output, EventEmitter, OnInit} from 'angular2/core';
import {ObservableWrapper} from 'angular2/src/facade/async';
@Component({
selector: 'sample',
template: `<p>a sample</p>`
})
export class SampleComponent implements OnInit {
@Output() cancel: EventEmitter<any> = new EventEmitter();
private isCancelUsed: boolean;
ngOnInit(): void {
this.isCancelUsed = ObservableWrapper.hasSubscribers(this.cancel);
}
}
与 user1448982 相同的方法,但不使用 ObservableWrapper
,这意味着平台代码不会通过 api.
(使用 Angular 2 RC1 和 TypeScript)
注意:这只从 2.0.0-beta.16 和更高版本开始工作
import {Component, Output, EventEmitter} from '@angular/core';
@Component({
selector: 'sample',
template: `<p>a sample</p>`
})
export class SampleComponent {
@Output() cancel = new EventEmitter();
private isCancelUsed = false;
ngOnInit() {
this.isCancelUsed = this.cancel.observers.length > 0;
}
}
ObservableWrapper.hasSubscribers
方法在内部执行此行,因此您可以在此处执行相同的操作。
使用 TypeScript 时,如果 Angular 最终将 EventEmitter
从 Subject
更改为 [=16= =], 因此 .observers
属性).
更新 (03 / 2022)
observers
属性自 rxjs v7 起已弃用。您现在可以使用一个布尔值来指示主题是否正在使用,而不是检查观察者数组的长度。
// Old approach
this.isCancelUsed = this.cancel.observers.length > 0;
// New approach
this.isCancelUsed = this.cancel.observed;
Angular 12 删除了 EventEmitter#observables
字段,因此接受的答案不再有效。
现在的替代解决方案是转换为 Subject:
get hasOutputEventSubscriber() {
return (this.cancel as Subject).observers;
}
请注意,此 属性 也已弃用,将在 rxjs v8 中删除。一个面向未来的解决方案是为 EventEmitter 编写自定义包装器 class。
这是一个不依赖于 Angular 或 rxjs 的任何内部结构的未来证明示例。这是一个围绕 EventEmitter
的简单包装器,它公开了一个 subscriberCount
属性,当订阅者是 added/removed.
class WatchedEventEmitter extends EventEmitter<any> {
private _subscriberCount = 0;
get subscriberCount(): number {
return this._subscriberCount;
}
subscribe(next?: (value: any) => void, error?: (error: any) => void, complete?: () => void): Subscription {
++this._subscriberCount;
return super.subscribe(next, error, complete);
}
unsubscribe() {
--this._subscriberCount;
super.unsubscribe();
}
}
用法示例:
@Component({template: `
{{click.subscriberCount|json}}
<span *ngIf="cancel.subscriberCount">
<button mat-icon-button (click)="cancel.emit()">Click Me</button>
</span>
<span *ngIf="!cancel.subscriberCount">No Subscribers</span>
`})
export class SomeComponent {
@Output() cancel = new WatchedEventEmitter();
}
当前版本 Angular 13 检查是否有任何 observer/callback 提供你可以使用 this.cancel.observed
它将 return boolean
import {Component, Output, EventEmitter} from '@angular/core';
@Component({
selector: 'sample',
template: `<p>a sample</p>`
})
export class SampleComponent {
@Output() cancel = new EventEmitter();
private isCancelUsed = false;
ngOnInit() {
this.isCancelUsed = this.cancel.observed;
}
}