我正在寻找一个关于为什么使用@Output
进行事件的参数比在Angular 2 中传递@Input
函数更好。
使用@Input
:
父模板:
<my-component [customEventFunction]=myFunction></my-component>
parent-component.ts内部:
myFunction = () => {
console.log("Hello world")
}
My-component.ts
@Input() customEventFunction: Function;
someFunctionThatTriggersTheEvent() {
this.customEventFunction();
}
使用@Output
:
父模板:
<my-component (onCustomEvent)=myFunction()></my-component>
parent-component.ts内部:
myFunction() {
console.log("Hello world")
}
My-component.ts
@Output() onCustomEvent: EventEmitter<any> = new EventEmitter<any>();
someFunctionThatTriggersTheEvent() {
this.onCustomEvent.emit();
}
都实现了相同的目标,但是我认为@Output
方法比我在其他角包装中看到的更典型。有人可以说,使用输入,您可以检查是否存在该函数是否仅应有条件触发。
想法?
@Output事件的优点绑定:
- 使用@Output定义事件清楚地表明,它希望使用标准的角度机制和语法来处理该事件。
- 许多活动处理程序可以订阅@ouptut事件。另一方面,如果您定义了接受回调函数的@Input属性,则只能注册一个事件处理程序;分配第二个事件处理程序将断开第一个事件。要与标准DOM事件处理程序并行,@Input回调函数绑定类似于设置
onmousemove="doSomething()"
,而@Output事件绑定更像是调用btn.addEventListener("mousemove", ...)
。
@sajeetharan的答案实际上并不十分正确:是一个重要的功能差异:执行上下文。考虑这种情况:
@Component({
selector: 'app-example',
template: `<button (click)="runFn()">Click Me</button>`,
})
export class ExampleComponent {
@Input() public fn: any;
public runFn(): void {
this.fn();
}
}
@Component({
selector: 'app',
template: `<app-example [fn]="myFn"></app-example>`,
})
export class AppComponent {
public state = 42;
// Using arrow syntax actually *will* alert "42" because
// arrow functions do not have their own "this" context.
//
// public myFn = () => window.alert(this.state);
public myFn(): void {
// Oops, this will alert "undefined" because this function
// is actually executed in the scope of the child component!
window.alert(this.state);
}
}
这实际上使使用@Input()
属性传递功能非常尴尬。至少它打破了至少令人惊讶的原则,并且可以引入偷偷摸摸的虫子。
当然,在某些情况下,也许您不需要上下文。例如,也许您有一个可搜索的列表组件,该组件允许复杂的数据作为项目,并且需要传递fnEquals
函数,以便搜索可以确定搜索输入文本是否匹配项目。但是,这些情况通常通过更合并的机制(内容投影等)来更好地处理,从而提高可重复性。
功能中的基本上是 no differences
,但是
(i)当您使用 @input
时,您可以使用 @Input
获得优势,因为我们可以定义类型以及它是私有的还是私有的
(ii)作为 @ConnorsFan
在评论中提到的,使用 @Ouput
的优点是许多订户可以处理输出事件,而只能为<<strong> @Input
属性。