Все текстовые вводимые данные обновляются, когда я нажимаю только на одну кнопку

#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 (), и это работает так же хорошо.