Сохранение и доступ к данным из сервиса в angular 7

Недавно я начал изучать последнюю версию angular с новым синтаксисом, но я знаком с Angular v1.

Я работаю над проектом ionic (v4.12.0), ниже приведен пример службы angular (v7.2.15) TodoService

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class TodoService {
  private todos = [];

  constructor(private http: HttpClient) {
    console.info('Constructor TodoService');
  }

  list() {
    // log shows this.todos as empty, always
    return this.todos;
  }

  add(todo object) {
    this.todos.push(todo);
    // log shows this.todos having 1 element now. it never goes beyond 1 irrespective of the number of todos added from the modal form 
  }

}

Я создал модальное окно TodoAddPage для чтения из формы и добавления записи в todos в TodoService

import { Component, Input, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { ModalController } from '@ionic/angular';
import { TodoService } from './todo.service';

@Component({})
export class TodoAddPage implements OnInit {
    constructor(
      private modalController: ModalController,
      private todoService: TodoService
    ) {}

    close() {
      this.modalController.dismiss({
        dismissed: true
      });
    }

    onSubmit(todo: object) {
      this.todoService.add(todo);
      this.close();
    }
}

Страница TodosPage для списка дел из TodoService

import { Component, OnInit } from '@angular/core';
import { AlertController, ModalController } from '@ionic/angular';
import { TodoAddPage } from './todo-add.page';
import { TodoService } from './todo.service';

@Component({})
export class TodosPage implements OnInit {

  public todos = [];

  constructor(
    private modalController: ModalController,
    private todoService: TodoService
  ) {
    this.todos = this.todoService.list();
  }

  ngOnInit() {
  }

  async add() {
    const modal = await this.modalController.create({
      component: TodoAddPage,
      componentProps: { value: 123 }
    });

    await modal.present();

    const { data } = await modal.onWillDismiss();
    console.info(data);

    console.info(this.todoService.list()); // Issues: This is always empty
  }

}

Проблема в том, что TodoService.list() всегда возвращает пустой список. Я проверил добавление логов в функции TodoService.add. И данные, кажется, находятся в TodoService.todos после .push в функции .add. Но если я получу к нему доступ, немедленно закрыв модальное окно, содержимое, возвращаемое функцией .list(), будет пустым.

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

можете ли вы создать stackblitz, чтобы мы могли его запустить

Sadid Khan 16.07.2019 11:18
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
1
90
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Позвонив в службы, у вас есть два варианта.

Опция 1 Доступ к самому списку задач. Это лучший случай для получения предопределенных задач:

 constructor(private todoService: TodoService){
    this.todos = this.todoService.todos;
  }

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

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';

@Injectable()
export class TodoService {
  private todos = [];
  todosSubject = new BehaviorSubject<any[]>([]);

  constructor(private http: HttpClient) {}

  list(): Observable<any[]> {
    return this.todosSubject.asObservable();
  }

  add(todo: any) {
    this.todos.push(todo);
    this.todosSubject.next(this.todos);
  }

}

и на вашей странице вызовите функцию подписки на список:

  public todos = [];

  constructor(private modalController: ModalController, private todoService: TodoService) 
  {
    this.getTodos();
  }

  getTodos()
  {
    this.todoService.list().subscribe((data) => { this.todos = data });
  }

Надеюсь, что это ответ на ваш вопрос.

Ответ принят как подходящий

Разобрался с вопросом.

При публикации вопроса я абстрагировался от определения компонента, как показано ниже.

@Component({})
export class TodoAddPage implements OnInit {}

Но фактическое содержание Component было

@Component({
  selector: 'app-todo-add',
  templateUrl: './todo-add.page.html',
  styleUrls: ['./todo-add.page.scss'],
  providers: [TodoService] // This was the one causing the issue
})

Удалил провайдеров (не уверен, когда и почему я добавил туда) выше, и это решило проблему.

@Component({
  selector: 'app-todo-add',
  templateUrl: './todo-add.page.html',
  styleUrls: ['./todo-add.page.scss'],
})

Другие вопросы по теме