#.net #angular #reference #ngfor
Вопрос:
В настоящее время я работаю над личным проектом с Angular и .NET API с SQL Server для серверной части. Теперь я не хотел использовать внешние ключи, потому что тогда вы зависите от базы данных. Таким образом, в моих моделях есть идентификаторы, на которые ссылаются другие объекты.
Основная цель приложения-создание списка задач, в котором указывается, выполнена ли задача и кому она поручена. Таким образом, модель задачи имеет атрибут с именем: «responsible_user_id»: 1, например. Число 1 означает, что пользователь с идентификатором = 1 отвечает за эту задачу. Но 1 мало что значит на интерфейсе, я хочу показать имя пользователя.
Теперь у меня есть следующее:
<div class="container">
<div class="row" >
<div class="col-4" *ngFor="let task of categoryTasks">
<div class="card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">{{task.item_title}} </h5>
----->>> <h5 class="card-title">Reponsible user: {{task.responsible_user_id}} </h5>
<h5 *ngIf="(task.item_status)"> <i style="color:rgb(34, 216, 34);" class="bi bi-check-circle"></i>
</h5>
<h5 *ngIf="(!task.item_status)"> <i style="color:red;" class="bi bi-x"></i>
</h5>
<br>
<button (click)="setDone(task.item_id)" class="btn btn-primary">Done</button>
</div>
</div>
</div>
</div>
</div>
Я разместил стрелки в строке, где я хочу, чтобы отображалось имя пользователя. В настоящее время я могу показать только идентификатор, но для получения указанного пользователя необходим еще один новый вызов API. Все, что я пробовал, приводило к множеству ошибок, пока программа не вышла из строя.
Метод, который я пробовал, создавал метод в файле component.ts:
public GetResponsibleUser(id){
var user:any;
this.userService.getUser(id).pipe(first())
.subscribe(res => user = res);
var name = user.username;
return name;
}
который я бы назвал из строки выше со стрелками перед ним, но это не сработало.
Есть ли кто-нибудь, кто знает, как решить эту проблему?
Заранее спасибо!!
С уважением, Джулиус
Ответ №1:
Ваша функция GetResponsibleUser
работает не так, как это, так как вам пришлось бы возвращать наблюдаемое:
NOT-WORKING!
public GetResponsibleUser(id): Obserable<User> {
return this.userService.getUser(id).pipe(first())
}
И в HTML вам нужно будет добавить асинхронный канал:
<h5 class="card-title">Reponsible user: {{GetResponsibleUser(task.responsible_user_id) | async }}</h5>
Но это все равно приведет к огромному количеству вызовов на серверную часть, так как каждый раз, когда вызывается obserable (вызов завершен), обнаружение изменений angulars будет выполняться и создаст следующий вызов этого метода. -> Заканчивается бесконечным звонком.
Вы могли бы создать своего рода кэш в своем компоненте или даже лучше в a Service
.
Просто в качестве примера:
private cache = new Map<string, string>();
GetResponsibleUser(userId: string): Observable<string> {
if (this.cache.get(userId)) {
return of(this.cache.get(userId));
} else {
return this.userService.getUser(userId)
.pipe(
first(),
map(user => user.getUsername()),
tap(username => this.cache.set(userId, username))
);
}
}
Ответ №2:
***Не делайте этого!!! Это неправильно:
getUsersName(id) {
return this.usersService.getUser().pipe(
map(user => user.Name)
)
}
и в шаблоне:
{{ getUsersName(user.id) }}
Если вы поставите наблюдаемых из HTTP-запроса в шаблон с помощью асинхронных трубы — приложение будет делать 7 запросов для каждого изменения детектор итерации и ответы будут изменения данных и пожарной изменить детектора -> детектор обновления данных и труб пожара -> асинхронный трубопроводов(подписывается) потоки и огонь детектор снова , потому что Нг зоне позвонить детектора, когда HTTP-запрос случилось цикла!!!**
Если вы не можете добавить поле «Имя» для списка пользователей, см. Пример работы:
stackblitz-пример с пользователями и их сообщениями в ваших именах обращений
**почему .pipe(first()) не поможет ? — потому что приложение будет создавать новый поток с первым каналом каждый раз, когда вызывается метод, возвращающий поток. Таким образом, он работает только для потоков, возвращающих данные в нескольких итерациях. Также его можно использовать для потоков с одной итерацией — для отмены подписки на поток после ответа, — но если ответ будет слишком длинным, вы можете оставить компонент, а обратный вызов подписки может быть попыткой использовать несуществующие свойства умершего компонента.