从 Angular 组件中删除输出属性值
Remove Output attribute value from Angular component
我想过这个实验是从我有时需要为我的 Angular 组件的输出添加和删除功能的情况得出的。
这是例子
Parent 组件将只包含 child 组件 <my-component>
.
的输出函数
Parent组件
class ParentComponent{
myOutputFunction = null;
setOutputFunction() {
this.myOutputFunction = () => {
// do something
};
}
removeOutputFunction() {
this.myOutputFunction = null;
}
}
Parent组件
的模板
<my-component (someOutput)="myOutputFunction($event)"><my-component>
Child 组件 MyComponent
内部会有输出 someOutput
。这也将作为一个问题如何检测 parent 何时决定执行 removeOutputFunction()
并可能订阅该事件并对其做出反应。
MyComponentchild组件
class MyComponent {
@Output() someOutput = new EventEmitter();
ngOnInit(): void {
// At this point we can see if there are any observers to someOutput
if(this.someOutput.observers.length > 0) {
console.log('YEY we have a set output method from ParentComponent to MyComponent`s attribute');
} else {
console.log('We have no attribute defined');
}
}
}
在ngOnInit()
中我们可以检查我们是否编码了(someOutput)="myOutputFunction($event)"
.
所以,结论。
有没有办法听(订阅)someOutput
从 parent 从 () => // do something
值到 null
值的变化。
当我登录 this.someOutput.observers
时,我得到了订阅者数组。
我可以使用 this.someOutput
作为 EventEmitter 以某种方式到达这个实验指向的地方吗?
谢谢
这是一个非常有趣的想法。
但为了确保您在正确的时间得到它,您应该听取 'newListener' 事件并在那里执行您的逻辑。检查此 link 作为参考 https://nodejs.org/api/events.html#events_event_newlistener
....
this.someOutput.once('newListener', (event, listener) => {
... // you have a listener
})
...
一旦你使用模板,你不能通过观察者的数量来推断任何东西。即使你这样做了:
<my-component (someOutput)="myOutputFunction"><my-component>
如果 myOutputFunction
为 null,则观察者数量仍为 1。
您可以使用 ViewChild
有条件地设置观察者(不 建议的方法,请参阅以下原因*):
@ViewChild(MyComponent, { static: true }) comp: MyComponent;
myOutputFunction = null;
setOutputFunction() {
this.myOutputFunction = () => {
console.log('something');
};
this.comp.someOutput.subscribe(this.myOutputFunction);
}
查看演示:https://stackblitz.com/edit/angular-output-programmatic
但是,恕我直言,您的做法是错误的。如果有人在听,您似乎希望 child 组件(有条件地)产生一些结果。
- 使用 EventEmitter 来推断这是错误的;如果您希望 child 组件中的行为依赖于 myOutputFunction,请将 @Input() 传递给 child 组件 - 最简单的是,传递
myOutputFunction
本身并让 child 组件调用它。或者:
- 总的来说,这听起来像是一个可观察对象的用例:如果(且仅当)有人订阅它,就应该产生一些东西。消费者是parent,生产者是child。接受救援
- 这样的模式听起来与组件无关;考虑将 observable/subject 放入服务中。
您可能已经了解所有这些,所以我将其保留为:不,不要将逻辑基于 EventEmitter 的观察者。 *即使你采用程序化方法,你也打破了一些基本的抽象;正确使用 - 和 - child 组件的行为需要消费者对 child 组件逻辑有复杂的了解。
您不能动态删除输出属性,但我认为这个解决方案可以帮助您。
如果你想设置从 parent 到 child 的值,你应该在 child 组件中使用 @Input
。
@Output
用于通知从child到parent的东西。
解决方案 1
如果您希望 children 仅在 parent 具有功能时发出值,请在有人收听时告诉 child 组件。
假设您发出的值是 string
类型
Child 组件
class MyComponent {
@Output() someOutput: EventEmitter<string> = new EventEmitter();
@Input() isParentListening = false;
ngOnInit(): void {
if (this.isParentListening) {
// Parent wants to receive data
this.someOutput.emit("Yay! Parent is listening");
} else {
// Parent is not listening
console.log("My parent doesn't take care of me :(");
}
}
}
Parent 组件
<my-component
[isParentListening]="listenChildComponent"
(someOutput)="myOutputFunction($event)"
></my-component>
class ParentComponent {
listenChildComponent = true;
myOutputFunction = (value: string) => {
// do something
};
}
解决方案 2
另一种解决方案是保持 child 组件干净并且不知道此逻辑,并且 parent 决定它是否必须做某事。
Child 组件
class MyComponent {
@Output() someOutput: EventEmitter<string> = new EventEmitter();
ngOnInit(): void {
// Output always as if someone were listening
this.someOutput.emit("Yay! Someone is listening (I hope)");
}
}
Parent 组件
当输出事件发生时,parent 根本不执行任何逻辑。
<my-component (someOutput)="()=>{}"></my-component>
class ParentComponent {}
为什么不使用输入?
class MyComponent {
@Input() func = null;
ngOnInit(): void {
if (func)
func();
else
console.log("I'm child")
}
}
在你的parent
<app-child [func]="functionInParent"></app-child>
functionInParent()
{
console.log("function in parent")
}
//OR
<app-child></app-child>
我想过这个实验是从我有时需要为我的 Angular 组件的输出添加和删除功能的情况得出的。 这是例子
Parent 组件将只包含 child 组件 <my-component>
.
Parent组件
class ParentComponent{
myOutputFunction = null;
setOutputFunction() {
this.myOutputFunction = () => {
// do something
};
}
removeOutputFunction() {
this.myOutputFunction = null;
}
}
Parent组件
的模板<my-component (someOutput)="myOutputFunction($event)"><my-component>
Child 组件 MyComponent
内部会有输出 someOutput
。这也将作为一个问题如何检测 parent 何时决定执行 removeOutputFunction()
并可能订阅该事件并对其做出反应。
MyComponentchild组件
class MyComponent {
@Output() someOutput = new EventEmitter();
ngOnInit(): void {
// At this point we can see if there are any observers to someOutput
if(this.someOutput.observers.length > 0) {
console.log('YEY we have a set output method from ParentComponent to MyComponent`s attribute');
} else {
console.log('We have no attribute defined');
}
}
}
在ngOnInit()
中我们可以检查我们是否编码了(someOutput)="myOutputFunction($event)"
.
所以,结论。
有没有办法听(订阅)someOutput
从 parent 从 () => // do something
值到 null
值的变化。
当我登录 this.someOutput.observers
时,我得到了订阅者数组。
我可以使用 this.someOutput
作为 EventEmitter 以某种方式到达这个实验指向的地方吗?
谢谢
这是一个非常有趣的想法。 但为了确保您在正确的时间得到它,您应该听取 'newListener' 事件并在那里执行您的逻辑。检查此 link 作为参考 https://nodejs.org/api/events.html#events_event_newlistener
....
this.someOutput.once('newListener', (event, listener) => {
... // you have a listener
})
...
一旦你使用模板,你不能通过观察者的数量来推断任何东西。即使你这样做了:
<my-component (someOutput)="myOutputFunction"><my-component>
如果 myOutputFunction
为 null,则观察者数量仍为 1。
您可以使用 ViewChild
有条件地设置观察者(不 建议的方法,请参阅以下原因*):
@ViewChild(MyComponent, { static: true }) comp: MyComponent;
myOutputFunction = null;
setOutputFunction() {
this.myOutputFunction = () => {
console.log('something');
};
this.comp.someOutput.subscribe(this.myOutputFunction);
}
查看演示:https://stackblitz.com/edit/angular-output-programmatic
但是,恕我直言,您的做法是错误的。如果有人在听,您似乎希望 child 组件(有条件地)产生一些结果。
- 使用 EventEmitter 来推断这是错误的;如果您希望 child 组件中的行为依赖于 myOutputFunction,请将 @Input() 传递给 child 组件 - 最简单的是,传递
myOutputFunction
本身并让 child 组件调用它。或者: - 总的来说,这听起来像是一个可观察对象的用例:如果(且仅当)有人订阅它,就应该产生一些东西。消费者是parent,生产者是child。接受救援
- 这样的模式听起来与组件无关;考虑将 observable/subject 放入服务中。
您可能已经了解所有这些,所以我将其保留为:不,不要将逻辑基于 EventEmitter 的观察者。 *即使你采用程序化方法,你也打破了一些基本的抽象;正确使用 - 和 - child 组件的行为需要消费者对 child 组件逻辑有复杂的了解。
您不能动态删除输出属性,但我认为这个解决方案可以帮助您。
如果你想设置从 parent 到 child 的值,你应该在 child 组件中使用 @Input
。
@Output
用于通知从child到parent的东西。
解决方案 1
如果您希望 children 仅在 parent 具有功能时发出值,请在有人收听时告诉 child 组件。
假设您发出的值是 string
Child 组件
class MyComponent {
@Output() someOutput: EventEmitter<string> = new EventEmitter();
@Input() isParentListening = false;
ngOnInit(): void {
if (this.isParentListening) {
// Parent wants to receive data
this.someOutput.emit("Yay! Parent is listening");
} else {
// Parent is not listening
console.log("My parent doesn't take care of me :(");
}
}
}
Parent 组件
<my-component
[isParentListening]="listenChildComponent"
(someOutput)="myOutputFunction($event)"
></my-component>
class ParentComponent {
listenChildComponent = true;
myOutputFunction = (value: string) => {
// do something
};
}
解决方案 2
另一种解决方案是保持 child 组件干净并且不知道此逻辑,并且 parent 决定它是否必须做某事。
Child 组件
class MyComponent {
@Output() someOutput: EventEmitter<string> = new EventEmitter();
ngOnInit(): void {
// Output always as if someone were listening
this.someOutput.emit("Yay! Someone is listening (I hope)");
}
}
Parent 组件
当输出事件发生时,parent 根本不执行任何逻辑。
<my-component (someOutput)="()=>{}"></my-component>
class ParentComponent {}
为什么不使用输入?
class MyComponent {
@Input() func = null;
ngOnInit(): void {
if (func)
func();
else
console.log("I'm child")
}
}
在你的parent
<app-child [func]="functionInParent"></app-child>
functionInParent()
{
console.log("function in parent")
}
//OR
<app-child></app-child>