Я начинаю с 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)
, удаляющий объект с таким именем из массива.
Это правильно, или я что-то упускаю?
Еще одно сомнение: это аккуратный и правильный способ справляться с событиями и подобными ситуациями?