Есть ли в angular 8 хук жизненного цикла, который вызывается при нажатии кнопки элементов - PullRequest
0 голосов
/ 09 января 2020

У меня есть основной компонент, который содержит два вложенных компонента, один из компонентов содержит поля ввода (2) и кнопку для добавления элемента, а другой компонент-брат отображает элементы в al oop.

У меня есть сервис, который выбирает значения из компонента ввода и обновляет его массив в самом сервисе.

Всякий раз, когда я заполняю входные данные и отправляю сервис, он добавляет новый элемент в массив, но мне нужно обновить родственный компонент, для отображения которого необходим этот список.

Я знаю, что должен получить значения из службы, поскольку у нее обновленный массив.

Я не знаю, какой хуй lifecylce можно использовать в компоненте для получения списка друзей, чтобы получить новый список, так как кажется, что ngOnInit не вызывается при нажатии кнопки Добавить.

Я не хочу использовать источник событий.

Родительский компонент

export class ShoppingComponent implements OnInit {
  ingredients:Ingredient[];

  constructor(private shoppingListService: ShoppingListService) { }

  ngOnInit() {
    this.ingredients = this.shoppingListService.getIngredients();
  }

} 

родительский html

<div class="row">
    <div class="col-md-10">
        <app-shoppinglistedit></app-shoppinglistedit>
        <hr>
        <app-shoppinglist></app-shoppinglist>
    </div>
</div>

Два дочерних компонента, помещенные в родительский компонент:

Список сестер

export class ShoppinglistComponent implements OnInit {
  ingredients: Ingredient[];

  constructor(private shoppingListService: ShoppingListService) { }

  ngOnInit() {
    this.ingredients = this.shoppingListService.getIngredients();
    this.oldLength = this.ingredients.length;
  }

}

это HTML / шаблон

<ul class="list-group">
    <a class="list-group-item" *ngFor="let ingridient of ingredients" >
        {{ ingridient.name }} <span class="badge badge-success badge-pill ml-auto">{{ ingridient.amount }}</span>
    </a>
</ul>

Добавляющий брат

export class ShoppinglisteditComponent implements OnInit {
  @ViewChild('nameRef', {static: true}) itemName:ElementRef;
  @ViewChild('amountRef', {static: true}) itemAmount:ElementRef;

  constructor(private shoppingListService: ShoppingListService) { }

  ngOnInit() {
  }

  onAddNewItem(){
    const name = this.itemName.nativeElement.value;
    const amount = +this.itemAmount.nativeElement.value;
    const ingredient = new Ingredient(name, amount);

    this.shoppingListService.addIngredient(ingredient);
    console.log("All ingredients: ");
    console.log(this.shoppingListService.getIngredients());

  }
}

это шаблон - html

<div class="row col-sm-12">
    <form>
        <div class="row">
            <div class="form-group col-sm-5">
                <label for="name">Name</label>
                <input id="name" class="form-control" type="text" name="name" #nameRef>
            </div>
            <div class="form-group col-sm-2">
                <label for="amount">Amount</label>
                <input id="amount" class="form-control" type="number" name="amount" #amountRef>
            </div>
        </div>
        <div class="row">
            <div class="col-md-12">
                <button class="btn btn-success mr-2" type="button" (click)="onAddNewItem()">
                    <i class="fas fa-plus-circle"></i>&nbsp;Add Item
                </button>
                <button class="btn btn-danger mx-2" type="button">
                    <i class="far fa-trash-alt" (click)="onDeleteIngredient()"></i>&nbsp;Delete Item
                </button>
                <button class="btn btn-primary mx-2" type="button">
                    <i class="fas fa-adjust" (click)="onClearItem()"></i>&nbsp;Clear Item
                </button>
            </div>
        </div>
    </form>
</div>

1 Ответ

2 голосов
/ 09 января 2020

Если вы не используете EventEmitter, это будет сложно, потребляет ресурсы процессора и не реагирует. Позвольте мне предложить вам кое-что:

Сначала создайте @Input() ingredients: Ingredient[] для вашего компонента ShoppinglistComponent . Вы уже получили ингредиенты в своем родительском компоненте, так что вы можете передать их любому дочернему компоненту (в нашем случае ShoppinglistComponent). Затем добавьте @Output() ingredientAdded = new EventEmitter() к вашему компоненту ShoppinglisteditComponent , который вы запустите внутри вашего onAddNewItem метод. В вашем ShoppinglistComponent прослушайте вывод (ingredientAdded)="insertNewIngredient($event)"

insertNewIngredient(addedIngredient: Ingredient): void {
  this.ingredients = this.ingredients.concat(addedIngredient)
}

Когда вы передадите свои ингредиенты в ShoppinglistComponent с вводом, он автоматически обновит ваше представление. Нет необходимости в ловушках жизненного цикла, просто используйте некоторый честный реактивный код.

PS:

Вы действительно должны использовать реактивные формы или формы на основе шаблонов в своих ShoppinglisteditComponent так как вы хотите управлять формой, а Angular очень хорошо это делают (не изобретайте велосипед). Вот некоторый код с использованием реактивных форм (не забудьте включить FormsModule и ReactiveFormsModule

  form: FormGroup;

  constructor(
    fb: FormBuilder,
    private shoppingListService: ShoppingListService
  ) {
    this.form = fb.group({
      name: ['', Validator.required],
      amount: [0, [Validator.required, Validator.min(0)]]
    })
  }

  onAddNewItem(){
    const { name, amount } = this.form.value;
    const ingredient = new Ingredient(name, amount);
    this.shoppingListService.addIngredient(ingredient);
    console.log("All ingredients: ");
    console.log(this.shoppingListService.getIngredients());
  }
<div class="row col-sm-12">
    <form [formGroup]="form" (ngSubmit)="onAddNewItem()">
        <div class="row">
            <div class="form-group col-sm-5">
                <label for="name">Name</label>
                <input formControlName="name" id="name" class="form-control" type="text" required>
            </div>
            <div class="form-group col-sm-2">
                <label for="amount">Amount</label>
                <input formControlName="amount" id="amount" class="form-control" type="number" required>
            </div>
        </div>
        <div class="row">
            <div class="col-md-12">
                <button class="btn btn-success mr-2">
                    <i class="fas fa-plus-circle"></i>&nbsp;Add Item
                </button>
                <button class="btn btn-danger mx-2" type="button">
                    <i class="far fa-trash-alt" (click)="onDeleteIngredient()"></i>&nbsp;Delete Item
                </button>
                <button class="btn btn-primary mx-2" type="button">
                    <i class="fas fa-adjust" (click)="onClearItem()"></i>&nbsp;Clear Item
                </button>
            </div>
        </div>
    </form>
</div>
...