RxJS Предметы и компоненты Angular2
Я смиряюсь с тем фактом, что веб-разработка меняется, и мне нужно разобраться с RxJS. В настоящее время я занимаюсь разработкой веб-приложения с использованием Angular 2.0.0-beta.15.
Я слежу за самой превосходной нг-книгой 2 (разрешена ли такая реклама? Хорошо). Он охватывает широкими, мелкими штрихами некоторые важные понятия в RxJS и предоставляет ссылки для дальнейшего чтения. Я прочитал и понял исходный код и сопровождающее его объяснение, но я остался немного в неведении относительно некоторых деталей, касающихся Subject
В частности, и о том, как компоненты Angular 2 потребляют эти тематические потоки.
Я добавил код из книги таким образом:
export class SubmitResourceComponent {
private _newResourceTags: Subject<Tag> = new Subject<Tag>();
private _resourceTags: Observable<Tag[]>;
private _tagUpdates: Subject<any> = new Subject<any>();
private _create: Subject<Tag> = new Subject<Tag>();
private _remove: Subject<Tag> = new Subject<Tag>();
constructor() {
this._resourceTags = this._tagUpdates
.scan((tags: Tag[], operation: ITagsOperation) => operation(tags), initialTags);
this._create
.map((tag: Tag): ITagsOperation => (tags: Tag[]) => _.uniq(tags.concat(tag)))
.subscribe(this._tagUpdates);
this._remove
.map((tag: Tag): ITagsOperation => (tags: Tag[]) => _.without(tags, tag))
.subscribe(this._tagUpdates);
this._newResourceTags.subscribe(this._create);
}
get resourceTags(): Observable<Tag[]> {
return this._resourceTags;
}
protected addTagToResource(tag: Tag): void {
this._create.next(tag);
}
protected removeTagFromResource(tag: Tag): void {
this._remove.next(tag);
}
}
И я потребляю _resourceTags
как это:
<button class="btn" *ngFor="#tag of resourceTags | async" (click)="removeTagFromResource(tag)">{{ tag.name }}</button>
То, что я не могу понять, даже с отличной поддержкой со стороны форумов Gitter, это то, почему пользовательский интерфейс отображает все теги, которые вставляются в _resourceTags
Subject
, Я бы предположил, что поток похож на резиновую трубу: когда элемент проталкивается в Subject
и опубликовано на что угодно Observer
(в данном случае, элемент пользовательского интерфейса), разве он не испаряется и не исчезает? Останется ли он в потоке / трубе /Subject
? Как элемент пользовательского интерфейса подписывается на Subject
? Думаю ли я об этом неправильно? Нужна ли полная психическая перестройка / пересадка?
Так много вопросов!
2 ответа
Данные переданы next
это как событие. Подписчик получает значение и Observable
созданный Subject
не содержит никаких ссылок на него (за исключением того, что вы используете специальные операторы с целью буферизации или другими средствами для сохранения выданных значений).
С | async
Angular подписывается на Observable
(Subject
) и когда оно получает значение, оно отображает его.
*ngFor
только рендеринг массивов. Если вы хотите использовать *ngFor
с Subject
субъект должен излучать массивы - каждое событие представляет собой не одно значение, а массив значений, и эти значения отображаются *ngFor
и заменены другими значениями, когда Observable
испускает новый массив
Ваш пример кода использует scan
Оператор с целью накопления излучаемых значений и пересылки массива, который содержит все значения, выпущенные до сих пор, каждый раз, когда он получает новое событие, как того требует *ngFor
,
Я думаю, что observables хранит значения переменной в памяти браузера только до тех пор, пока сеанс не будет очищен, как если бы вы установили переменную для получения значения из поля ввода и после нажатия на кнопку "Обновить" в браузере значения опустели. В вышеприведенном сценарии я бы подумал, что, как и большинство SPA, браузер не имеет возможности по умолчанию обновлять / перезагружать, и вы получаете какое-то постоянство, поэтому, когда вы выполняете такую операцию, как
... _.uniq(tags.concat(tag))).subscribe(this._tagUpdates);...
значения продолжают накапливаться, поскольку они объединяются событием create, но исчезают, когда происходит обновление страницы вручную и очищает сеанс
РЕДАКТИРОВАТЬ
Возможно, я неправильно понял вопрос, но я имею в виду следующее: _resourceTags начинается пусто, значение создается событием create, теперь _resourceTags is [newValue # 1] angular обнаруживает изменения и повторно отображает _resourceTags с помощью ngFor, после нового события create _resourceTags is сейчас [newValue#1, newValue#2] угловые рендеры, показывающие оба сейчас. Если поток не сохраняется в онлайн-базе данных, такой как firebase, или в автономной, такой как websql, это означает, что после перезагрузки браузера _resourceTags вернется к пустым