Как именно работает этот пример Angular 5, обрабатывающий связь между родительским и дочерним компонентами?

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

Итак, у меня есть РОДИТЕЛЬСКИЙ КОМПОНЕНТ. Этот компонент используется для отображения списка элементов (каждый элемент представлен дочерним компонентом). Взаимодействуя с этим компонентом, я могу добавлять и удалять элементы из этого списка.

Это родительский компонент:

@Component({
  selector: 'app-products',
  templateUrl: './products.component.html'
})
export class ProductsComponent {

  productName = 'A Book';
  isDisabled = true;

  products = ['A Book', 'A Tree'];

  constructor() {

    setTimeout(
      () => {
        this.isDisabled = false;
      }, 3000)
  }


  onAddProduct() {
    this.products.push(this.productName);

  }

  onRemoveProduct(productName: string) {
    this.products = this.products.filter(p => p !== productName);
  }

}

А это его шаблон:

<h1>My Products</h1>

<input *ngIf="!isDisabled" type="text" [(ngModel)]="productName">

<button *ngIf="!isDisabled" (click)="onAddProduct()">Add Product</button>

<app-product
    (productClicked)="onRemoveProduct(product)"
    *ngFor="let product of products"
    [productName]="product">
</app-product>

Затем у меня есть дочерний компонент, представляющий один элемент списка, обрабатываемый родительским компонентом. Это дочерний компонент:

@Component({
  selector: 'app-product',
  templateUrl: './product.component.html',
  styleUrls: ['./product.component.css']
})
export class ProductComponent {

  @Input() productName: string;

  @Output() productClicked = new EventEmitter();

  onClicked() {
    this.productClicked.emit();
  }

}

А это детский шаблон:

<article class="product" (click)="onClicked()">
  <div>{{ productName }}</div>
  <p>An awesome product!</p>
</article>

Хорошо, теперь у меня есть некоторые сомнения относительно того, как эти 2 компонента взаимодействуют вместе:

В шаблоне родительского компонента:

<app-product
    (productClicked)="onRemoveProduct(product)"
    *ngFor="let product of products"
    [productName]="product">
</app-product>

это относится к дочернему компоненту (помеченному как app-product).

Мне кажется, что в основном я повторяю список продуктов, определенный в родительском классе компонента (массив строк), и что каждая из этих строк передается в переменную productName, определенную в классе дочернего компонента. , для этого я использую декоратор @Input() для этого свойства в классе дочерних компонентов:

@Input() productName: string;

По сути, этот декоратор @Input () позволяет родительскому компоненту «вставлять» значение в свойство дочернего компонента на каждой итерации.

Это? или я что-то упускаю?

Затем у меня есть поведение, которое обрабатывает удаление элемента из списка элементов: когда элемент списка щелкает (реализуется дочерним компонентом). Этот элемент удаляется из списка (и, следовательно, со страницы).

Как это работает (моя идея):

Каждый элемент представлен этим кодом в представлении дочернего компонента:

<article class="product" (click)="onClicked()">
  <div>{{ productName }}</div>
  <p>An awesome product!</p>
</article>

При щелчке по объекту выполняется событие onClicked() в классе дочерних компонентов. Я не могу удалить выбранный объект непосредственно из класса дочернего компонента, потому что массив элементов определен в классе родительского компонента. Итак, этот метод генерирует событие:

  onClicked() {
    this.productClicked.emit();
  }

имеющий "тип" productClicked (это тип события или что?). Это событие принимается в представлении родительского компонента:

(productClicked)="onRemoveProduct(product)"

которые вызывают метод onRemoveProduct(product), удаляющий объект с таким именем из массива.

Это правильно, или я что-то упускаю?

Еще одно сомнение: это аккуратный и правильный способ справляться с событиями и подобными ситуациями?


person AndreaNobili    schedule 15.05.2018    source источник
comment
Все, что вы объяснили, правильно, и именно так вы должны вести себя при таком общении. Престижность!   -  person Roberto Zvjerković    schedule 15.05.2018
comment
Выглядит правильно. Я не вижу ничего, что я бы не сделал по-другому, проработав с Angular 1,5 года.   -  person Phil    schedule 15.05.2018


Ответы (1)


Вы правы в обоих случаях!

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

person Guillaume Ruchot    schedule 15.05.2018