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