Обновление пользовательского интерфейса с использованием канала ASYNC и возвращаемой наблюдаемой <{}> - PullRequest
1 голос
/ 06 марта 2019

Я нахожусь в весьма затруднительном положении, и это может быть подход, который я использовал, изучая rxJS и Observables.

Введение

Наше приложение использует Angular для подключения к нашему общедоступному уровню API (C #). Тип объекта, который возвращается из моего вызова ASYNC, имеет Observable . Этот поток передается дочернему компоненту, который проходит по элементам. Этот же поток также позволяет пользователю добавлять новые заметки типа NoteDto или редактировать заметки. В идеале, когда эти действия будут выполнены, список заметок будет отражать обновленное изменение без необходимости вызова того же сервисного вызова для повторного получения заметок.

Код

[notes.component.html]

<div *ngIf="(notes$ | async)?.items as notes; else loading">
    <note-card [noteData]="notes" (noteClick)="editNote($event)"></note-card>
</div>
<ng-template #loading>
    <div class="notes__container">
        <div class="note-card">
            <div class="note-card__primary-action">
                <div class="note-card__head">
                    <h2 class="note-card__title note-card-typography--headline1 text-center">Loading...</h2>
                </div>
            </div>
        </div>
    </div>
</ng-template>

[notes.component.ts]

import ...

@Component({
    ...
})
export class NotesComponent extends AppComponentBase implements OnInit {
    constructor(
        ...
        private _noteService: NoteServiceServiceProxy
    ) {
        super(injector);
    }

    public notes$: Observable<ListResultDtoOfNoteDto>;
    public userId: number;
    ...

    ngOnInit() {
        ...
        this.getNotes();
        ...
    }

    getNotes(): void {
        /*
            Binding to ASYNC pipe; which doesn't need a subscription since it is automatic?
            Returns type: Observable<ListResultDtoOfNoteDto> which is an array of NoteDto
        */
        this.notes$ = this._noteService.getUserNotes(this.userId, null);
        ...
    }
    ...

    public saveNote(note: NoteDto, mode: string) {
        if (mode === 'new') {
            this._noteService.addNote(note).subscribe(() => {
                this.cleanUp();
                this.getNotes();
                this.notify.info(this.l('SavedNoteSuccessfully'));
            });
        } 
        ...
    }
}

Все функции за вычетом события clickEvent в дочернем элементе происходят внутри родительского элемента. Который загружает форму (методология реактивной формы), которая может принять новую заметку и сохранить или изменить более старую заметку для обновления.

Мой номер

Мне просто нужен способ сохранить заметку и обновить список без необходимости повторного вызова this.getNotes () в подписке при добавлении новой заметки.

(могу предоставить более подробную информацию, если необходимо!)

РЕДАКТИРОВАТЬ: Забыл показать метод сохранения в настоящее время

1 Ответ

1 голос
/ 07 марта 2019

Один из способов добиться этого - иметь в своем NoteServiceServiceProxy личный BehaviorSubject , который всегда будет содержать последнее значение заметок.

Как: private _notes = new BehaviorSubject<ListResultDtoOfNoteDto>(null)

  • и вы публикуете функцию, предназначенную только для потребителей, чтобы подписаться.
  • Ваш вызов API обновит тему только с ответом
public getNotes(): Observable<ListResultDtoOfNoteDto> {
    return this._notes.asObservable();
}

public getNotesFromApi(args): {
    // Api request
    this.httpClient.get().pipe(tap(result) => this._notes.next(result))
    // etc...
}

Тогда все, что вам нужно сделать в вашем компоненте, это объявить наблюдаемое что-то вроде

notesData = this. _noteService.getNotes();

внутри init просто сделайте запрос к API, чтобы получить заметки, и он автоматически обновит вашnotesData, который должен быть подписан на ваш шаблон через async трубу вывода.

Когда вы сохраняете все, что вам нужно сделать, это просто добавить concatMap в конце, чтобы сначала сохранить, а затем запроситьобновление от вашего API.

Так что-то вроде

    this._noteService.addNote(note).pipe(
        concatMap(() => this._noteService.getNotesFromApi()))
        .subscribe();

Это снова обновит вашу переменную notesData, которая есть в шаблоне.

Я надеюсь, вы понимаете, как работает этот поток, и если нет, то не стесняйтесьспросить.

Надеюсь, это поможет!

...