Понимание ngOnInit

Я делаю курс udemy по angular и наткнулся на этот код. У меня есть пример проекта, в котором есть кнопка «Добавить элемент», которая добавляет новый элемент в массив и отображает обновленный массив на экране.

покупка-edit.component.ts

export class ShoppingEditComponent implements OnInit {

  @Input() ingredientsArray : Ingredient[];

  shoppingItemName : string = 'Test';
  shoppingItemAmount : number = 66;

  constructor(private shoppingListService : ShoppingListService) { }

  ngOnInit() {
  }

  onItemAdd(){
    console.log(this.shoppingItemName)
    this.shoppingListService.addIngredient(this.shoppingItemName, this.shoppingItemAmount);
  }

}

У меня есть эмиттер событий, который испускает обновленный массив при нажатии кнопки «Добавить».

список покупок.service.ts

ingredientsChanged = new EventEmitter<Ingredient[]>();

addIngredient(name: string, value : number){
  this.ingredients.push(new Ingredient(name, value));
  this.ingredientsChanged.emit(this.ingredients.slice());
} 

Чтобы отобразить список, я использую shopping-list.component.ts.


export class ShoppingListComponent implements OnInit {

  constructor(private shoppingListService : ShoppingListService){}

  ingredients : Ingredient[];


  ngOnInit() {
    this.ingredients = this.shoppingListService.getIngredients();
    this.shoppingListService.ingredientsChanged.subscribe(
      (ingredients : Ingredient[]) => {
        this.ingredients = ingredients;
      }
    )
    console.log("hello")
  }

}

Поскольку ngOnInit() для shopping-list.component.ts запускается только один раз, как обновляющийся список отображается каждый раз, когда нажимается кнопка «Добавить»?


person sanjeev u rao    schedule 30.09.2019    source источник
comment
Это связано с наблюдаемыми объектами. Я не буду давать ответ, потому что я бы только повторял документацию, но это важная часть Angular, я предлагаю вам хотя бы прочитать документацию по Angular, чтобы понять основы!   -  person    schedule 30.09.2019
comment
Пока у вас есть активная подписка на наблюдаемый компонент inventoryChanged, код, указанный в методе подписки в вашем компоненте, выполняется, когда значение наблюдаемого изменяется и значения вашего компонента обновляются.   -  person Fussel    schedule 30.09.2019


Ответы (3)


Ваш список не обновляется в ngOnOInit. Вы подписываетесь только на наблюдаемое в ngOnInit. Поэтому всякий раз, когда вы получаете новые данные в своей подписке, вы обновляете переменную, а затем из-за того, что ngOnChanges запускается, что обновляет ваше представление.

person Aviso    schedule 30.09.2019
comment
дайте мне знать, если вам нужны дополнительные разъяснения - person Aviso; 30.09.2019

каждый раз, когда вы вызываете onItemAdd(), вы обновляете элемент, который находится в обслуживании (используя эту строку кода: this.shoppingListService.addIngredient(this.shoppingItemName, this.shoppingItemAmount);)

И HTML будет отображаться с использованием shoppingListService.ingredients (например: - <div *ngFor="let ingredient of shoppingListService.ingredients > //here you will get individual ingredient </div>)

person Shafeeq Mohammed    schedule 30.09.2019

Это больше связано с тем, как работают rxjs Observables, чем с ngOnInit. Подписки прослушивают события до тех пор, пока подписка не будет отменена. Если вы хотите, чтобы он принимал только первый элемент, вы должны сделать это:

this.shoppingListService.ingredientsChanged.pipe(take(1)).subscribe(
      (ingredients : Ingredient[]) => {
        this.ingredients = ingredients;
      }
    )
person ShamPooSham    schedule 30.09.2019