Угловой компонент: могу ли я использовать Observable вместо EventEmitter как свойство @Output()?
[угловой 2.4.5]
Я пробовал и, похоже, работает как EventEmitter:
-
Мой компонент извне:
<split (visibleTransitionEnd)="log($event)"></split>
-
Внутри компонента:
@Output() visibleTransitionEnd: Observable<string>
observer: Observer;
constructor() {
const myObs = new Observable(observer => this.observer = observer);
this.visibleTransitionEnd = myObs
.map(x => '> ' + x + ' <')
.debounceTime(20)
.do(() => console.log('here we are!'));
}
-
Затем я могу вызвать внутренний компонент:
// needed condition because if nobody subscribe 'visibleTransitionEnd' > no observer!
if(this.observer) this.observer.next('test');
Посмотреть этот плункер
Мне это нравится, потому что внутри моего компонента нет подписки.
Но это плохой способ достичь этого? Что такое риск/не так?
Лучше ли использовать Subject
?
Ответы
Ответ 1
Ну, в вашей ситуации вы можете использовать EventEmitter
или Subject
. Вы можете видеть, что EventEmitter
похож на Subject
(хотя рекомендуется использовать EventEmitter
если можно). https://github.com/angular/angular/blob/master/modules/%40angular/facade/src/async.ts
Функция Observable.create
(или new Observable()
) не предназначена для использования подобным образом. Внутренняя функция должна излучать значения наблюдателю и возвращать функцию разрыва (освободить ресурсы или что-то еще). Не быть сохраненным как собственность.
Однако я не уверен, какие последствия он может иметь (утечки памяти?).
Поэтому скорее используйте Subject
:
export class SplitComponent implements OnDestroy {
@Output() visibleTransitionEnd: Observable<string>
visibleTransitionEndObserver: Subject;
constructor() {
const subject = new Subject();
this.visibleTransitionEnd = subject.asObservable()
.map(x => '> ' + x + ' <')
.debounceTime(20)
.do(() => console.log('here we are!'));
}
// ...
}
Ответ 2
EventEmitter
просто расширяет Subject
, поэтому это неудивительно (и я тоже это видел в Dart).
Они используют свой собственный класс, чтобы иметь возможность изменять реализацию позже, не нарушая существующий код.
Так что, возможно, не лучшая идея обойти эту абстракцию. Если вы осознаете недостаток и готовы принять его, вы, конечно, можете это сделать.