将事件传递给指令并订阅它

Posted

技术标签:

【中文标题】将事件传递给指令并订阅它【英文标题】:Pass event to directive and subscribe to it 【发布时间】:2018-11-06 16:59:55 【问题描述】:

我有一个具有 EventEmitter 输出的指令。 我想在订阅发出的事件返回订阅完成后做点什么。

(例如,我想在 example.component 的 save() 完成时执行 console.log('test')。 - 我知道我可以在 example.component 的 save 方法中执行此操作,但我正在这样做一些通用的东西,所以我在指令中需要它)。

import  Directive, OnInit, HostListener, Output, EventEmitter  from '@angular/core';

@Directive(
  selector: '[appSingleActiveButton]'
)
export class SingleActiveButtonDirective 
  @Output() appSingleActiveButton: EventEmitter<any> = new EventEmitter();

  constructor() 

  @HostListener('click', ['$event'])
  private onClick(e: any): void 
    this.appSingleActiveButton.next(e);
    //determine somehow that the referred function's subscription is completed and do something
    // for example what I tried is: this.appSingleActiveButton.subscribe(() => console.log('do some other stuff'))
  

我有一个组件,它有一个带有该指令的元素并传递一个返回订阅的函数。

example.component.ts:

import  Component  from '@angular/core';
import  Subscription  from 'rxjs/Rx';
import  Http  from '@angular/http';

@Component(
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.scss'],
)
export class ExampleComponent 

  constructor(private http: Http) 

  public save(index: number): Subscription 
    const requestUrl = 'http://example.com';
    return this.http
    .get(requestUrl)
    .map((response) => response.json()).subscribe(() => console.log(`doing some stuff $index`));
  

example.component.html

<div *ngFor="let btn of btns; let i = index">
    <div (appSingleActiveButton)="save(i)">test directive</div>
</div>

编辑: 问题如下:

我如何确定 save() 在我实际调用它的指令内完成(成功或错误)this.appSingleActiveButton.next(e);

【问题讨论】:

问题是什么?您的解决方案是否有问题? 问题如下,我将编辑上面的帖子:如何确定指令中的save()完成(成功或错误)。 【参考方案1】:

按照我之前的回答和您的解释,这次我解决了您的问题。

对于您的解决方案,您可以通过多种方式来做您想做的事。

    鉴于指令只做同样的事情(HTTP 调用)

为此,您可以简单地将 URL 作为参数传递给指令,并让指令处理 HTTP 调用。您可以使用@Output 检索订阅并在您的组件中订阅它。

    鉴于他们做的事情略有相似,并希望将逻辑保留在您的组件中

您可以将您的函数save 直接作为@Input 传递给您的指令。单击后,您可以运行此功能,然后再次使用@Output 获取订阅。

您也可以直接在构造函数中引用您的元素,并在点击时调用该元素的函数。

这些是您可以实施的解决方案。如果您在代码方面需要帮助,请随时提出要求,但我不会那样给您,因为我不是您的代码猴子,而尝试是最好的学习方式。

【讨论】:

第一个解决方案不好,因为我不只做http请求(除了url还有不同的变量),我也在为这些请求做不同的成功/错误,最重要的是在我为每个请求所做的事情中,我想再添加一件事,这就是我使用指令的原因。关于第二个解决方案 - 我已经尝试过并且效果很好,直到我不得不通过参数。 const parentComponent = (this.viewContainerRef.injector as any).view.component; this.appSingleActiveButton.call(parentComponent, e).add(() =&gt; this.onRequestResponse()); 然后将参数作为数组传递给您的指令,以便它知道它们。而且我说的不是注射器,这是繁重的处理,您应该改用elementRef 是的,我正在考虑通过它们,会调查一下,谢谢!

以上是关于将事件传递给指令并订阅它的主要内容,如果未能解决你的问题,请参考以下文章

CE 更新事件:有啥方法可以将之前/之后的属性值传递给工作流?

自定义vue点击事件传递数据

React:是不是可以将事件传递给底层 iframe?

我在监视触摸事件的 UITableViewCell 中有一个 UILabel,如何将一些事件传递给单元格,将其他事件传递给标签?

如何将 X11 事件传递给 QDialog

RxJava 手动发出项目