Как отобразить значения в выпадающем списке в Angular?

#angular #typescript

#angular #typescript

Вопрос:

Я реализовал 2 выпадающих списка, как показано ниже

введите описание изображения здесь

При выборе категории из первого выпадающего списка, в соответствии с выбранным значением, она присвоит значения второму выпадающему списку.

Но когда приложения запускаются в первый раз, при первом выпадении (выберите категорию) вниз не будет отображаться какое-либо значение. Если выбрать второй выпадающий список (Выбрать элемент), а затем, когда я нажимаю на первый выпадающий список, присваиваются все значения. В чем может быть проблема?

Ниже приведена реализация

component.html

         <div class="row ml-3 mr-3 mt-3">
            <label class="col-form-label">Select Category :</label>
            <select class="form-control" [(ngModel)]="selectedItemType" (ngModelChange)="selectItemType()">
                <option value="" [selected]="true"> Please choose one </option>
                <option *ngFor="let item of items">{{item}}</option>
            </select>
        </div>
        <div class="row ml-3 mr-3 mt-5">
            <label class="col-form-label">Select Item :</label>
            <select class="form-control" [(ngModel)]="selectedItemName" (ngModelChange)="selectItemName()">
                <option value="" [selected]="true"> Please choose one </option>
                <option *ngFor="let selectedItem of selectedItems">{{selectedItem.itemName}}</option>
            </select>
        </div>
  

component.ts

 import {Component, OnInit, SimpleChange} from '@angular/core';

import { DashboardService} from "@modules/dashboard/services";
import {element} from "protractor";

@Component({
  selector: 'cashier',
  templateUrl: './cashier.component.html',
  styleUrls: ['./cashier.component.scss']
})
export class DashboardItemsComponent implements OnInit {
    items : String[];
    selectedItems : {itemName : String, price : number}[] = [];
    addedItems : {itemName : String, quantity : number, price : number}[] = [];
    selectedItemType : String = ''
    selectedItemName : String = ''

  constructor(
     private dashboardService : DashboardService
  ) {
  }

  ngOnInit(): void {
        setTimeout(() => {
            this.dashboardService.getItems()
                .subscribe(response => {
                    this.items = response    //<-------- this will retrieve values for first drop down from the backend API
                })
        }, 1000)

      console.log(this.items)
  }

  selectItemType(){
     let tempSelectedItems : {itemName : String, price : number}[] = [];
        this.dashboardService.getItemsByType(this.selectedItemType)
            .subscribe( response => {
                for(let item of response){                   //<-------- this will retrieve values for second drop down from the backend API
                    tempSelectedItems.push({itemName : item.itemName, price : item.price})
                }
                this.selectedItems = tempSelectedItems;
            })
  }

  selectItemName(){
        console.log(this.selectedItemName)
  }


  add(){
        //implentation
  }
}

  

service.ts

 import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import {map} from "rxjs/operators";
import { HttpClient } from '@angular/common/http';

@Injectable()
export class DashboardService {
    constructor(private http: HttpClient) {}

    getDashboard$(): Observable<{}> {
        return of({});
    }

    getItems(){
        return this.http.get<any>('http://localhost:8080/rest/items/types')
            .pipe(map(items => {
                if(items){
                    return items;
                }
            }))
    }

    getItemsByType(type){
        let tempSelectedItems : {itemName : String, price : number}[] = [];
        return this.http.get<any>('http://localhost:8080/rest/items/itemsByType', {params : { itemType : type}})
            .pipe(map( items => {
                if(items){
                    // return items;
                    for(let i of items){
                        tempSelectedItems.push({itemName : i.itemName, price : i.price})
                    }

                    return tempSelectedItems;
                }
            }))
    }
}

  

Комментарии:

1. Первая проблема, потому что начальное значение selectedItemType пусто. Предоставьте код для selectItemName метода для анализа второй проблемы.

2. Я попытался повторить вашу проблему, но в моей реализации все было в порядке: stackblitz.com/edit/angular-ivy-gtjlte?file=src/app /…

3. не получено никакой ошибки: stackblitz.com/edit/angular-ivy-bnstt5?file=src/app /…

4. Я ничего не реализовал в selectItemName методе. Просто журнал консоли. Я обновлю вопрос, предоставляющий selectItemName метод. Можете ли вы, пожалуйста, проверить? @uiTeam324

5. но в моем браузере это вызывает у меня эту проблему! @programoholic 🙁 🙁 🙁 : (

Ответ №1:

Похоже, что с кодом нет никаких проблем, и если вы посмотрите на опубликованный stackblitz, они, похоже, работают.

Итак, я бы посоветовал вам сократить код до минимума и начать оттуда.

 <div class="row ml-3 mr-3 mt-3">
    <label class="col-form-label">Select Category :</label>
    <select class="form-control">
       <option value=""> Please choose one </option>
       <option *ngFor="let item of items">{{item}}</option>
    </select>
</div>
  

Начните только с приведенного выше кода в шаблоне и посмотрите, работает ли он. Мы можем продолжить оттуда.

Примечание: setTimeout не требуется. Пожалуйста, удалите это и используйте только в случае крайней необходимости.

Обновление 1:

 constructor(
 private dashboardService : DashboardService,
 private changeDetectorRef: ChangeDetectorRef
) { }

ngOnInit(): void {
  this.dashboardService.getItems().subscribe(response => {
      this.items = response;
      this.changeDetectorRef.detectChanges(); // This should be used temporarity until the actual issue is located.
  });
}
  

Примечание 2. Не используйте String, Number, Boolean в качестве типов. Вместо этого используйте string, number, boolean
Ссылка:https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html

Комментарии:

1. Хорошо, как только я попробовал таким образом, та же ситуация продолжается. Когда я нажимаю где-нибудь в браузере (пробел), он загружает и отображает данные

2. Так что наверняка не срабатывает перехват жизненного цикла обновления пользовательского интерфейса. Вы удалили setTimeout()? Если это все еще не работает, значит, ваша проблема в другом месте. Пока не будет найдена фактическая проблема, вы можете временно ввести ChangeDetectorRef в конструктор и запустить this.changeDetectorRed.DetectChanges() при установке this.items = response;

3. Я попытаюсь найти реальную проблему. И предложенный способ работает. Спасибо за помощь!

4. Следует помнить еще одну вещь. Не используйте String, используйте string