#angular #typescript
Вопрос:
У меня есть компонент с кнопкой увеличения и уменьшения. Я просматриваю продукты, и кнопки отображаются рядом с каждым продуктом. Когда я нажимаю на одну из кнопок, обновляются все текстовые вводимые данные, а не только тот, на который я нажал.
КОМПОНЕНТ HTML:
<div *ngFor="let product of products">
<button (click)="minus()" type="button">
-
</button>
<input id="number" type="text" value="1" [(ngModel)]="count">
<button (click)="plus()" type="button">
</button>
</div>
КОМПОНЕНТНЫЙ МАШИНОПИСНЫЙ ТЕКСТ:
count: number = 1;
plus(){
this.count ;
}
minus(){
if (this.count > 1) {
this.count--;
}
}
Когда я использую:
<div *ngFor="let product of products; let i = index">
<input id="number" type="number" value="1" [(ngModel)]="products[i].count">
</div>
Я получаю ошибку:
Свойство «количество» не существует для типа » {идентификатор: число; имя: строка; цена: число; описание: строка; }».
Когда я использую:
<input id="number" type="number" value="1" [(ngModel)]="product[i].count">
Я получаю ошибку:
Элемент неявно имеет тип «любой», поскольку выражение типа «число» не может использоваться для индексирования типа » {идентификатор: число; имя: строка; цена: число; описание: строка; }». Не было найдено подписи индекса с параметром типа «номер» для типа » {идентификатор: номер; имя: строка; цена: номер; описание: строка; }».
Массив продуктов определяется следующим образом:
export interface Product {
id: number;
name: string;
price: number;
description: string;
}
Ответ №1:
Это потому, что все они ссылаются на одну и ту же переменную из — за ngModel и того факта, что вы перебираете свои продукты и используете одну входную ссылку — поэтому, когда вы нажимаете кнопку и изменяете количество, все они будут обновляться, потому что все они прослушивают одну и ту же переменную.
<input id="number" type="text" value="1" [(ngModel)]="count">
Чтобы предотвратить это — вам нужно будет применить другую ссылку на ngModel для каждого, а также изменить функцию приращения и уменьшения, чтобы применять только к этому элементу.
<input id="number" type="text" value="1" (ngModel)]="products[index].count">
Комментарии:
1. Я отредактировал свой вопрос, чтобы показать, что я пытался, потому что не смог добавить комментарий. Мой вклад был слишком длинным, чтобы быть комментарием.
Ответ №2:
Проблема здесь в том, что вы определяете одну и ту же переменную для разных элементов массива. Решение состоит в том, чтобы присвоить значение счетчика каждому элементу массива. Для этого вам необходимо обновить значение счетчика всех элементов массива.
HTML
<div *ngFor="let product of products; let i=index">
{{product.name}}
<button (click)="minus(i)" type="button"> - </button>
<input id="number" type="text" [value]="product.count">
<button (click)="plus(i)" type="button"> </button>
</div>
МАШИНОПИСНЫЙ ТЕКСТ
export class AppComponent implements OnInit {
products: any[] = [
{ name: 'product 1' },
{ name: 'product 2' },
{ name: 'product 3' },
{ name: 'product 4' }
];
count: number = 1;
ngOnInit() {
this.migrateAllProducts();
}
migrateAllProducts() {
this.products.forEach(p => {
p.count = this.count;
});
}
plus(index: number) {
this.products[index].count ;
}
minus(index: number) {
if (this.products[index].count > 1) {
this.products[index].count--;
}
}
}
Комментарии:
1. Спасибо, Аноним. Мне сейчас нужно ложиться спать, так что я сделаю это завтра.
2. Я отредактировал свой вопрос, чтобы показать структуру массива продуктов. Я попробовал код Anonim, но получил ошибку: свойство «количество» не существует для типа » {идентификатор: номер; имя: строка; цена: номер; описание: строка; }».
3. Вы уверены, что написали функцию migrateAllProducts внутри функции ngOnInit? Я предлагаю вам проверить это. @Моринмур
4. В итоге я просто добавил количество в массив продуктов, и это сработало. Не элегантно, но этого достаточно.
5. Я удалил migrateAllProducts (), и это работает так же хорошо.