【问题标题】:Angular @Output: Can we detect if function is done when emitting?Angular @Output:我们可以检测发射时功能是否完成吗?
【发布时间】:2018-06-04 01:13:13
【问题描述】:

我有一个Angular Component 和一个Output。当我 emitevent 到这个 output 时,将调用一个 async 函数(这个函数在组件之外)。

component 内部,我想知道这个外部函数何时完成。有什么办法吗?

这是我的组件的一些代码:

@Output() action: EventEmitter<string>;

itemClicked(item) {
    this.action.emit();
    // When the function of the observer is done: this.hideMenu();
}

这是组件之外的代码:

<my-component (action)="getData()"></my-component>


getData() : Promise<any> {
    ...
}

有什么方法可以检测到组件内部的“getData”函数已经完成了吗?

在 AngularJS 中我可以这样做:

scope: {
    action: '&'
}
...

    scope.itemClicked = function(item) {
        $q.when(item.action()).finally(function() {
            scope.hideMenu();
        });
    };

编辑

我正在考虑另一个受Ionic 的复习启发的解决方案。如果 emit() 调用将我的组件实例作为参数传递怎么办?这样,getData 函数可以执行以下操作:

getData(menu): Promise<any> { 
    ...
    menu.hideMenu();
}

您如何看待这个解决方案?如果您认为这是错误的,那么我想我会选择 Input

【问题讨论】:

  • 您可以为此进行输入。类似:@Input() actionDone: boolean; 并将其设置在您的父组件中并将其传递给您的 my-component
  • 我会简单地为 menuHidden 定义一个输入属性:boolean trough a setter
  • 我编辑了我的帖子以添加我刚刚想到的可能的解决方案。你能告诉我你是怎么想的吗?

标签: angular output observable angular-components eventemitter


【解决方案1】:

我认为您应该在函数完成后使用@Input 发送完成的消息,并在感兴趣的组件中使用set 监听输入,并在知道函数完成后做您想做的事情。

【讨论】:

    【解决方案2】:

    AngularJS &amp; 绑定被错误地转换为 Angular。正确的对应物是Input:

    @Input() actionCallback: () => Promise<any>;
    
    itemClicked(item) {
        this.actionCallback().then(...);
    }
    

    使用如下:

    <my-component [actionCallback]="getData">
    

    虽然Output 提供不应该反馈的单向交互。 getData 应了解其职责并通过回调或 RxJS 主题提供反馈:

    @Output() action: EventEmitter<Function>;
    
    itemClicked(item) {
        this.action.emit(this.onClick);
    }
    
    onClick = () => {
      this.hideMenu();
    }
    

    使用如下:

    <my-component (action)="getData($event)"></my-component>
    
    getData(callback) : Promise<any> {
        ...
        .then(callback);
    }
    

    【讨论】:

    • 我使用了回调方法,您的“第二个”解决方案,它对我有用。也许@Input 解决方案在架构方面更好,但这个更简单所以我选择了它。谢谢!
    【解决方案3】:

    您可以像这样使用 Host 属性来获取父级

    @Output() action: EventEmitter<string>;
    
    constructor(@Host() private parent: ParentComponent) {
        parent.getData().subscribe(...);
    }
    

    EDIT将你的父类输入为抽象类

    constructor(@Host() private parent: ConcernedParent) {
        parent.getData().subscribe(...);
    }
    
    export abstract class ConcernedParent {
      public abstract getData(): Observable<any>;
    }
    

    【讨论】:

    • 这会将子组件与其父组件紧密耦合,但并非真正可重用
    • 正如 Jota.Toledo 所说,我希望这个组件可以在我的应用程序的多个地方使用,所以这个解决方案不适合我:)
    • 无论如何,如果你想重新使用它,请使用这个解决方案,而不是用一个组件输入你的父级,而是用一个接口/母类输入,它必须实现一个 getData功能。我的意思是,当然,您想重复使用它,但您仍然必须遵守某些规定,并且您至少可以遵守的是函数名称
    • 顺便说一句,这将在组件实例化时调用 getData 方法,但 OP 只想在事件发出时调用该方法。所以这并没有真正实现这一点。如果 getData 是一个在数据获取完成与否时会发出的可观察对象,那么您基本上是在定义一个输入属性,如另一个答案中已经解释的那样。
    • 当然像个疯子。我遵循了 OP 的签名,但我应该接受它。编辑了我的答案。如果你想让它在发出时,你可以将 getData 声明为主题。我根据他的要求回答了OP,他忘了提到关键因素。所以,是的,我在这里没有给出完整的答案,请像我对他一样容忍我!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 2013-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多