Передайте событие директиве и подпишитесь на нее

У меня есть директива с выводом EventEmitter. Я хотел бы что-то сделать, когда подписка на возвращаемую подписку на эмитированное событие завершена.

(например, я хотел бы сделать console.log('test') когда save() для example.component завершен. - Я знаю, что могу сделать это в методе сохранения example.component, но я делаю что-то общее, поэтому Мне это нужно в директиве).

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'))
  }
}

и у меня есть компонент, который имеет элемент с этой директивой и передает функцию, которая возвращает подписку.

пример.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}`));
  }
}

пример.component.html

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

EDIT: вопрос заключается в следующем:

Как я могу определить, что save() завершено (успех или ошибка) внутри директивы, где я на самом деле называю это this.appSingleActiveButton.next(e);


person Ron    schedule 28.05.2018    source источник
comment
В чем вопрос? Что-то не работает с вашим решением?   -  person user184994    schedule 28.05.2018
comment
Вопросы следующие, и я отредактирую сообщение выше: Как я могу определить, что save () завершено (либо успех, либо ошибка) в директиве.   -  person Ron    schedule 28.05.2018


Ответы (1)


Следуя моему предыдущему ответу и вашему объяснению, на этот раз я правильно понял вашу проблему.

Для вашего решения у вас есть несколько способов сделать то, что вы хотите.

  1. Учитывая, что директива делает то же самое (HTTP-вызовы)

Для этого вы можете просто передать URL-адрес в качестве параметра своей директиве и позволить директиве обрабатывать HTTP-вызов. Вы можете использовать @Output, чтобы получить подписку и подписаться на нее в своем компоненте.

  1. Учитывая, что они делают похожие вещи и хотят сохранить логику в вашем компоненте

Вы можете передать свою функцию save напрямую как @Input своей директиве. По щелчку вы можете запустить эту функцию и снова использовать @Output, чтобы получить подписку.

Вы также можете напрямую взять ссылку на свой элемент в конструкторе и при щелчке вызвать функцию этого элемента.

Это решения, которые вы можете реализовать. Если вам нужна помощь с кодом, не стесняйтесь просить об этом, но я не даю ее вам так, потому что я не ваша обезьяна в коде, а попытка — лучший способ научиться.

person Community    schedule 28.05.2018
comment
Первое решение не очень хорошее, потому что я выполняю не только HTTP-запросы (которые также имеют разные переменные, кроме URL-адреса), я также делаю разные вещи при успехе/ошибке для этих запросов, помимо того, что я делаю для каждого запроса Я хочу добавить еще одну вещь, поэтому я использую директиву. о втором решении - я уже пробовал это, и это работало хорошо, пока мне не пришлось передать параметры. const parentComponent = (this.viewContainerRef.injector as any).view.component; this.appSingleActiveButton.call(parentComponent, e).add(() => this.onRequestResponse()); - person Ron; 28.05.2018
comment
Затем передайте параметры в виде массива в свою директиву, чтобы она знала о них. И я не говорил об инжекторе, это тяжелая обработка, вместо этого вы должны полагаться на elementRef. - person ; 28.05.2018
comment
да, я думал о том, чтобы передать их, посмотрю на это, спасибо! - person Ron; 28.05.2018