繁体   English   中英

从 Angular 组件中删除输出属性值

[英]Remove Output attribute value from Angular component

我曾想过从我有时需要为我的 Angular 组件的输出添加和删除函数的情况下得出的实验。 这是例子

父组件将只包含子组件<my-component>输出函数。

父组件

class ParentComponent{
  myOutputFunction = null;

  setOutputFunction() {
    this.myOutputFunction = () => {
      // do something
    };
  }

  removeOutputFunction() {
    this.myOutputFunction = null;
  }
}

父组件模板

<my-component (someOutput)="myOutputFunction($event)"><my-component>

子组件MyComponent将输出someOutput内。 这也将作为一个问题,如何检测父级何时决定执行removeOutputFunction()并可能订阅该事件并对其做出反应。

MyComponent 子组件

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 from () => // do something值更改为null值。

当我记录this.someOutput.observers我得到了订阅者数组。 我可以以某种方式使用this.someOutput作为 EventEmitter 来到达这个实验所指向的地方吗?

谢谢

一旦使用模板,就无法通过查看观察者的数量推断出任何内容。 即使你做了:

<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

但是,恕我直言,您以错误的方式处理此问题。 如果有人在听,您似乎希望子组件(有条件地)产生一些结果。

  • 使用 EventEmitter 来推断这是错误的; 如果您希望子组件中的行为依赖于 myOutputFunction,请将 @Input() 传递给子组件 - 最简单的是,传递myOutputFunction本身并让子组件调用它。 或者:
  • 一般来说,这听起来像是 observable 的一个用例:如果(且仅当)有人订阅它,就应该产生一些东西。 消费者是父母,生产者是孩子。 受营救。
  • 这种模式听起来与组件无关; 考虑将 observable/subject 放在服务中。

您可能已经知道这一切,所以我将其保留在:不,不要将逻辑建立在 EventEmitter 的观察者之上。 *即使你采用程序化方法,你也已经破坏了一些基本的抽象; 正确使用 - 和来自 - 子组件的行为需要消费者对子组件逻辑有复杂的了解。

您无法动态删除输出属性,但我认为此解决方案可以帮助您。

如果要将值从父级设置为子级,则应在子组件中使用@Input

@Output用于通知子级到父级的内容。

解决方案1

如果您希望子组件仅在父组件具有函数时发出值,请在有人监听时告诉子组件。

让我们假设您发出的值是string类型

子组件

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 :(");
    }
  }
}

父组件

<my-component
  [isParentListening]="listenChildComponent"
  (someOutput)="myOutputFunction($event)"
></my-component>
class ParentComponent {
  listenChildComponent = true;

  myOutputFunction = (value: string) => {
    // do something
  };
}

解决方案2

另一个解决方案是保持子组件干净并且不知道这个逻辑,并且父组件决定它是否必须做某事。

子组件

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)");
  }
}

父组件

当输出事件发生时,父级根本不实现任何逻辑。

<my-component (someOutput)="()=>{}"></my-component>
class ParentComponent {}

为什么不使用输入?

class MyComponent {
  @Input() func = null;

  ngOnInit(): void {
    if (func)
       func();
    else
       console.log("I'm child")
  }
}

在你的父母

   <app-child [func]="functionInParent"></app-child>

   functionInParent()
   {
         console.log("function in parent") 
   }

   //OR
   <app-child></app-child>

这是一个非常有趣的想法。 但为了确保您在正确的时间获得它,您应该收听 'newListener' 事件并在那里执行您的逻辑。 检查此链接作为参考https://nodejs.org/api/events.html#events_event_newlistener

....
this.someOutput.once('newListener', (event, listener) => {
    ... // you have a listener
})

...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM