Недавно я начал изучать последнюю версию 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(), будет пустым.
Поведение кажется немного странным, кто-нибудь сталкивался с этой проблемой? или я что-то не так здесь делаю?





Позвонив в службы, у вас есть два варианта.
Опция 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'],
})
можете ли вы создать stackblitz, чтобы мы могли его запустить