Элемент не помещается в массив в классе Angular - PullRequest
0 голосов
/ 16 марта 2019

Я создал Angular Service, который хранит список элементов, к которым другие компоненты могут добавлять элементы и получать. По какой-то причине в список ничего не добавляется. Это происходит только в функции add () моего сервиса, но переменная не изменяется вне ее. Например, в конце функции add () консоль возвращает добавленный элемент. Но когда я проверяю список снова из функции getItems () список становится пустым. Почему список не обновляется вне функции после нажатия?

    export class BasketService {
      private list: Item[] = [];
      constructor() {}

      add(product: Product, units: number): void {
        let item: Item = new Item();
        item.product = product;
        item.units = units;
        this.list.push(item);
        console.log(this.list[(this.list.length - 1)]);
        // Log shows item object
      }
      getItems(): Observable<Item[]> {
        console.log(this.list);
        // Log shows empty array
        return of(this.list);
      }
    }

EDIT

getItems () действительно имеет подписчика, однако проблема, похоже, оттуда не возникает, поскольку он получает пустой массив Item, тот же пустой список, который печатается консолью в getItems (в basketService).

export class BasketComponent implements OnInit {
  items: Item[];

  constructor(private basketService: BasketService) {}

  ngOnInit() {
    this.getItems();
    console.log(this.items.length);
  }
  getItems(): void {
    this.basketService.getItems()
      .subscribe(items => {
        this.items = items; });
  }

Ответы [ 2 ]

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

Ваш метод getItems() возвращает Observable, содержащий ваш список элементов.Вы должны подписаться на этот Observable, чтобы получить предметы.

Кроме того, вы можете использовать BehaviorSubject для добавления списка в Observable каждый раз, когда список изменяется.

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

@Injectable()
export class BasketService {
  private list: Item[] = [];
  private subject = new BehaviorSubject<Item[]>([]);
  private list$ = this.subject.asObservable();

  add(product: Product, units: number): void {
    let item: Item = new Item();
    item.product = product;
    item.units = units;
    this.list.push(item);
    this.subject.next(this.list); // push the modified list to notify observers
  }
  getItems(): Observable<Item[]> {
    return this.list$;
  }
}

Используйте это так:

export class MyComponent implements OnInit {
  constructor(private service: BasketService) { }

  ngOnInit() {
    this.service.getItems().subscribe(items => {
      console.log('list modified', items); // this is executed after each list.push()
    });
  }
}

Вы также можете использовать scanс Subject и избавиться от переменной list.Список будет создан оператором scan путем добавления к предыдущим значениям:

@Injectable()
export class BasketService {
  private subject = new Subject<Item>();
  private list$ = this.subject.pipe(
    scan((list, item) => [...list, item], [] as Item[]),
  );

  add(product: Product, units: number): void {
    let item: Item = new Item();
    item.product = product;
    item.units = units;
    this.subject.next(item);
  }
  getItems(): Observable<Item[]> {
    return this.list$;
  }
}

Вот короткая демонстрация Stackblitz с использованием оператора сканирования.

0 голосов
/ 16 марта 2019

Убедитесь, что ваш сервис украшен @Injectable и предоставлен правильно, чтобы все ваши компоненты, использующие сервис, имели один и тот же экземпляр сервиса.

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