Привязать к @Output Наблюдаемое вместо обратного вызова?
У меня есть компонент слайдера, который испускает числа при перетаскивании ползунка, который можно использовать следующим образом: <my-slider (change)="onSlide($event)"></my-slider>
. Я хотел бы избавиться от метода onSlide
и вместо этого привязать поток событий change
к свойству Observable<number>
(вместо обратного вызова).
Я использую Angular 2 EventEmitter
для моего @Output
. EventEmitter
наследуется от RxJs Subject
, который является Observable
и Observer
. Я хочу повторно использовать сторону Observable
EventEmitter
.
Конечно, я могу передать значения, которые вводятся через onSlide
на другой Subject
, но я хочу предотвратить этот шаблон и накладные расходы. Есть ли способ?
Ответы
Ответ 1
Одно из основных различий между Angular 1 и Angular 2 заключается в том, что обнаружение изменений всегда выполняется сверху вниз. Это делает работу намного лучше. Также нет необходимости выполнять "стабилизацию" ($ digest loop), как это было в Angular 1.
В Angular 2 вы не можете "нажимать" изменение другим способом, за исключением испускания события с EventEmitter
/Subject
, поэтому Angular 2 может начать проверку компонентов Change Detectors.
Вот хорошая статья об этой теме.
Ответ 2
Не уверен, что релевантно или если это кому-то помогает: у меня возникла аналогичная проблема: я хотел использовать свойство типа Observable<number>
, предоставляемое компонентом в родительском компоненте.
После чтения Observables and Reactive Programming в Angular 2 я заметил, что мне нужно "обернуться" вокруг моей архитектуры и позволить parent создайте Observable
, а затем назначьте его дочернему элементу.
Поэтому вместо того, чтобы иметь MyComponent
с @Output()
типа Observable<number>
(который затем был инициализирован до new BehaviorSubject(0)
и изменен с использованием вызовов next
), я изменил MyComponent
на haven a @Input()
типа BehaviorSubject<number>
:
@Component({
selector: 'my-component',
template: `
<button (click)="increment()">Click me!</button>
`,
})
export class MyComponent {
private _count : number = 0;
@Input()
public counter : BehaviorSubject<number>;
public increment() {
this._count++;
if (this.counter)
this.counter.next(this._count);
}
}
Теперь родитель создает объект BehaviorSubject и привязывается к свойству. Он может легко использовать объект BehaviorSubject как наблюдаемый:
@Component({
selector: 'my-app',
template: `
<my-component [counter]="count"></my-component>
<span>{{text | async}}</span>
`,
})
export class App {
public text : Observable<string>;
public count : BehaviorSubject<number> = new BehaviorSubject(0);
constructor() {
this.text = this.count.map(n => "Click: " + n);
}
}
Plunker: https://plnkr.co/edit/rKtVWmmGnFn4Po4B4CCL?p=preview
Итак, в вашем случае я бы сказал, что ваш слайдер должен предоставить @Input
(может быть, назвать его значением или номером) и позволить родительскому объекту назначать наблюдаемое (вместо того, чтобы позволить ребенку создать его).