@HellYeahOmg

Как сделать реактивные данные в сервисе Angular?

Сервис содержит массив с книгами и книгу, которую нужно отредактировать. При изменении (добавлении) книги для редактирования в сервисе нужно чтобы изменение получал и компонент, в который "внедряется" сервис.
На данный момент мой код не работает, хотя есть другой компонент, который аналогично в конструкторе вызывает getBooks и сохраняет локально, там данные обновляются при каждом изменении массива в сервисе.
Обязательно ли здесь использование rxjs?
Сервис
import { Injectable } from "@angular/core";
import { Book } from "../models/book/book";

@Injectable({
  providedIn: "root"
})
export class BooksService {
  private books: Book[];

  private editingBook: Book; // book that needs to edit

  constructor() {
    this.books = JSON.parse(localStorage.getItem("books")) || [];
  }

  getBooks(): Book[] {
    return this.books;
  }

  getEditingBook(): Book {
    return this.editingBook;
  }

  addBook(book: Book): void {
    this.books.push(book);
    this.saveChanges();
  }

  deleteBook(book: Book): void {
    const index = this.books.findIndex(item => item.author === book.author);
    this.books.splice(index, 1);
    this.saveChanges();
  }

  editBook(book: Book): void {
    this.editingBook = book;
  }

  private saveChanges(): void {
    localStorage.setItem("books", JSON.stringify(this.books));
  }
}

Компонент
import { Component } from "@angular/core";
import { Book } from "src/app/models/book/book";
import { BooksService } from "src/app/services/books.service";

@Component({
  selector: "app-form",
  templateUrl: "./form.component.html",
  styleUrls: ["./form.component.sass"]
})
export class FormComponent {
  newBook: Book = {
    author: "",
    title: "",
    year: 0,
    pages: 0
  };

  editingBook: Book;

  constructor(private src: BooksService) {
    this.editingBook = this.src.getEditingBook(); // не обновляется
  }

  handleNewBook(): void {
    this.src.addBook(this.newBook);
    this.resetNewBook();
  }

  private resetNewBook(): void {
    this.newBook = {
      author: "",
      title: "",
      year: 0,
      pages: 0
    };
  }
}

  • Вопрос задан
  • 614 просмотров
Решения вопроса 1
Xuxicheta
@Xuxicheta Куратор тега Angular
инженер
Смотрите, чтобы данные визуально отобразились, нужно чтобы сработала детекция изменений в этом компоненте.
В случае использования rxjs, вызов подписок инициирует обнаружение изменений (ну на самом деле немного сложнее, но и так норм), а вот если вы просто объект поменяете, то нет. Придется как-то отслеживать эти вещи вручную.

хотя есть другой компонент, который аналогично в конструкторе вызывает getBooks и сохраняет локально, там данные обновляются при каждом изменении массива в сервисе

Скорее всего в этом компоненте есть какое-то взаимодействие с пользователем, генерация событий.

Обязательно ли здесь использование rxjs?

Можно ли работать с Ангуляром, но не использовать rxjs? Можно. К примеру дергать какое-нибудь событие, а компонент будет его слушать и выполнять detectChanges. Можно mobx к этому делу приспособить, например. Можно приделать каких-нибудь костылей наподобие vuex, т.е. сделать сеттеры, которые обновляют компонент. Или эффект в redux.
Нужно ли работать с Ангуляром, но не использовать rxjs? Безусловно нет. В сервисе данные храните как поток (сабджекты и их производных) или shareReplay, или исползуйте какие-то надстройки, типа ngrx и прочих.

Rxjs тесно связан с самим Ангуляром и используется практически везде, не знаешь rxjs - не знаешь Ангуляр.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы