#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
метод. Можете ли вы, пожалуйста, проверить? @uiTeam3245. но в моем браузере это вызывает у меня эту проблему! @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