从 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>