Подписка на источник событий, возвращающий неопределенное - PullRequest
0 голосов
/ 27 марта 2020

Я пытаюсь разрешить пользователю удалять ингредиенты из множества ингредиентов в своем списке покупок в моем приложении рецепта. Я создал источник событий, который срабатывает, когда пользователь нажимает кнопку удаления. Я подписываюсь на событие, но появляется следующее сообщение об ошибке: «Невозможно прочитать свойство« подписаться »из неопределенного».

Другая проблема, которую, я думаю, у меня возникнет, - это «ингредиент» (который представляет собой данные события Я понял) это не номер. Поскольку я использую это в методе сплайсинга, я не верю, что это сработает. Надеемся, что кто-то может помочь.

Вот соответствующий html код:

<div *ngIf="ingredients.length > 1">
    <div class="shopping-list-container">
        <img src="https://i.ya-webdesign.com/images/shopping-cart-icon-png-1.png" class="shopping-cart-image" alt="shopping cart">
        <ul>
            <li *ngFor="let ingredient of ingredients" class="shopping-list row">
                {{ ingredient.name }} - {{ ingredient.amount }}
                <img (click)="onDeleteItem(ingredient)" src="https://getdrawings.com/free-icon/delete-all-icon-63.png" alt="delete" class="delete-image">
            </li>
        </ul>
    </div>
</div>

вот источник событий, который создается в файле .service (я включил только соответствующие биты здесь):

import { EventEmitter } from '@angular/core';

@Injectable({
  providedIn: 'root'
})



  export class ShoppingListService {

   deleteItem = new EventEmitter<Ingredient>();

  }

вот файл .component (опять же, я включил только то, что имеет отношение):

import { ShoppingListService } from './shopping-list.service';

export class ShoppingListComponent implements OnInit {

ingredients: Ingredient[];

constructor(private shoppingListService: ShoppingListService) { }

ngOnInit() {

   this.shoppingListService.deleteItem.subscribe( 
      (ingredient: number) => {
        this.ingredients.splice(ingredient, 1);
      }
    );
  }

  onDeleteItem(ingredient) {
    this.shoppingListService.deleteItem.emit(ingredient)
  }

}

}

1 Ответ

2 голосов
/ 27 марта 2020

Вы не должны использовать EventEmitter в сервисах, это только для components

Вместо этого вам нужно использовать Observable с и BehaviorSubject/Subject с, как показано ниже

@Injectable({
  providedIn: 'root',
})
export class ShoppingListService { 
  itemDeleted : Subject<Ingredient> = new Subject<Ingredient>();
  private itemDeleted$: Observable<Ingredient> = this.itemDeleted.asObservable();

  deleteItem(item:Ingredient) {
    this.itemDeleted.next(item);
  }

}

в вашем компоненте

private unsubcribeAll: Subject<any> = new Subject<Any>();

ngOnInit() {

   this.shoppingListService.itemDeleted
   .pipe(
      takeUntil(this.unsubcribeAll)
    )
   .subscribe((ingredient: Ingredient) => {
        // this.ingredients.splice(ingredient, 1);
   });
}

ngOnDestroy() {
  this.unsubscribeAll.next();
  this.unsubscribeAll.complete();
}

onDeleteItem(ingredient) {
    this.shoppingListService.deleteItem(ingredient);
}

}

unsubcribeAll в приведенном выше коде используется для предотвращения утечки памяти и отписки от наблюдаемого

Решение 2

, если ваши компоненты находятся в одной иерархии, вы не нужны службы для информирования о действиях.

например

recipe.component

<section>
   <app-ingredient-list [ingredients]="recipeIngredients" (itemDeleted)="onItemDeleted($event)"></app-ingredient-list>
</section>

receipe.component.ts

  onItemDeleted(item:Ingredient) {
     // do what is needed here
  }

ингридиент-list.component.ts

  @Output() itemDeleted: EventEmitter<Ingredient> = new EventEmitter<Ingredient>();

  onDeleteButtonClick(item: Ingredient) {
    this.itemDeleted.emit(item);
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...