Данные, не обновленные напрямую с помощью Angular Observable Data Services - PullRequest
0 голосов
/ 24 июня 2018

Я реализовал Angular Observable Data Services, следуя этому учебнику в моем проекте.На самом деле, я столкнулся с проблемой обновления одного из двух моих объектов: мой Theme объект обновляется без проблем в Theme component, а topbar component в отличие от моего Category, который обновляется только наCategory component а не напрямую в topbar component.Мне нужно вернуться на мою домашнюю страницу, чтобы обновить мои topbar component.

test

Ниже моей модели реализации:

export class Theme {
  _id: string;
  name: string;
  description: string;
  iconCode: string;
  categories: Category[];
  createdAt: Date;
  updatedAt: Date;

export class Category {
  _id: string;
  name: string;
  description: string;
  createdAt: Date;
  updatedAt: Date;

Мой CategoryStoreService:

export class CategoryStoreService {

  private _categories: BehaviorSubject<Category[]> = new BehaviorSubject<Category[]>([]);
  private dataStore: {
    categories: Category[]
  };

  constructor(private categoryBackendService: CategoryBackendService) {
    this.dataStore = { categories: [] };
    this._categories = new BehaviorSubject<Category[]>([]);
  }

  get categories() {
    return this._categories.asObservable();
  }

  addThemeCategory(themeId: string, category: Category) {
    this.categoryBackendService.addThemeCategory(themeId, category).subscribe(
      res => {
        this.dataStore.categories.push(res);
        this._categories.next(Object.assign({}, this.dataStore).categories);
      },
      err => console.log('Error creating the category')
    );
  }

Мой ThemeStoreService:

export class ThemeStoreService {

  private _themes: BehaviorSubject<Theme[]> = new BehaviorSubject<Theme[]>([]);
  private dataStore: {
    themes: Theme[]
  };

  constructor(private themeBackendService: ThemeBackendService) {
    this.dataStore = { themes: [] };
    this._themes = new BehaviorSubject<Theme[]>([]);
  }

  get themes() {
    return this._themes.asObservable();
  }

  /**
   * Get the themes and their categories from the server and load it to the
   * data store
   */
  getThemes() {
    this.themeBackendService.getThemes().subscribe(
      res => {
        this.dataStore.themes = res;
        this._themes.next(Object.assign({}, this.dataStore).themes);
      },
      err => console.log("Error retrieving the themes")
    );
  }

Я подписался на мой ThemeStoreService в app.component.ts со следующим кодом:

export class AppComponent implements OnInit {

  themes$: Observable<Theme[]>;

  constructor(private themeStoreService: ThemeStoreService) { }

  ngOnInit() {
    // Subscribe to the themes
    this.themes$ = this.themeStoreService.themes;
    // Load all the themes
    this.themeStoreService.getThemes();
  }

И его шаблон:

<app-topbar [themes]="themes$ | async"></app-topbar>
<router-outlet></router-outlet>

И поскольку я подписался на Theme, который связан с моим Category полем categories в модели данных Темы, представлениене должно автоматически обновляться в моей верхней панели?

Верхняя панель - это немой компонент, получающий свойство themes через @Input () и отображающий темы и категории с помощью следующего кода:

<li class="nav-item dropdown" *ngFor="let theme of themes">
    <a class="nav-link dropdown-toggle" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
      <span [innerHTML]="theme.iconCode"></span>
      {{theme.name}}
    </a>
    <ul class="dropdown-menu" aria-labelledby="navbarDropdown">
      <li *ngFor="let category of theme.categories">
        <a class="dropdown-item" [routerLink]="['/threads']" [queryParams]="{ category: category._id }">
          {{category.name}}
        </a>
      </li>
    </ul>
  </li>

И файл .ts

export class TopbarComponent {

  @Input() themes: Theme[];

}

Как мне решить эту проблему?

Заранее спасибо за помощь.

1 Ответ

0 голосов
/ 24 июня 2018

Ваша проблема в том, что ваш дочерний компонент объявляет:

@Input() themes: Theme[];

И ваш родительский компонент передает асинхронный наблюдаемый поток :

<app-topbar [themes]="themes$ | async"></app-topbar>

, где themes$ имеет тип Observable.

[themes]="themes$ | async" не работает в пользовательской директиве ввода последней проверенной мной.Вам нужно извлечь данные из Observable themes $ вручную, используя Subscription, а затем передать данные:

import { ..., OnInit, OnDestroy } from ... //psuedo-code, add OnDestroy
import { ..., Subscription } from 'rxjs'; // psuedo-code, add Subscription

export class AppComponent implements OnInit, OnDestroy {

  themes: Theme[];
  themesSub: Subscription;

  constructor(private themeStoreService: ThemeStoreService) { }

  ngOnInit() {
    // Subscribe to the themes
    this.themesSub = this.themeStoreService.themes.subscribe({ data => this.themes = data });
    // Load all the themes
    this.themeStoreService.getThemes();
  }

  ngOnDestroy() {
    this.themesSub.unsubscribe();
  }

, не забудьте изменить html:<app-topbar [themes]="themes"></app-topbar>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...