为什么切换到交易子页面后看不到数据?
假设我有两页:第一页用于创建数据(交易),第二页用于在表格中显示交易。我也为这些子页设置导航('/create-transaction' 和 '/transactions'))。
我创建了一笔交易,它会写入数据库(Postgres),于是我跳转到 /users子页查看结果。点击链接后,页面什么都没有显示……再按F5刷新页面或再次点击导航中的链接,数据才会显示。我想知道为什么在跳转到子页后它们没有立即显示。
transactions-list.ts 和 create-transaction.ts
import { Component, inject, OnInit, signal } from '@angular/core';
import { NgClass } from '@angular/common';
import { TransactionsService } from '../../../core/services/transactions';
import { Transaction } from '../../../core/models/transaction.model';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-transaction-list',
standalone: true,
imports: [NgClass, CommonModule],
templateUrl: './transaction-list.html',
styleUrl: './transaction-list.scss',
})
export class TransactionList implements OnInit {
loading = signal(false);
private readonly transactionsService = inject(TransactionsService);
transactions: Transaction[] = [];
ngOnInit(): void {
this.loadTransactions();
}
loadTransactions(): void {
this.loading.set(true);
this.transactions = [];
this.transactionsService.getTransactions().subscribe({
next: (data) => {
console.log('Transactions loaded:', data);
this.transactions = [...data];
this.loading.set(false);
},
error: (error) => {
console.error('Error loading transactions:', error);
this.loading.set(false);
}
});
}
}
import { Component, EventEmitter, inject, Output, signal } from '@angular/core';
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { CategoriesService } from '../../../core/services/categories';
import { Category } from '../../../core/models/category.model';
import { TransactionsService } from '../../../core/services/transactions';
import { Transaction } from '../../../core/models/transaction.model';
@Component({
selector: 'app-create-transaction-form',
standalone: true,
imports: [CommonModule, ReactiveFormsModule],
templateUrl: './create-transaction-form.html',
styleUrl: './create-transaction-form.scss',
})
export class CreateTransactionForm {
// private fb = inject(FormBuilder);
private readonly fb = inject(FormBuilder);
private readonly transactionsService = inject(TransactionsService);
@Output() transactionCreated = new EventEmitter<Transaction>();
private readonly categoriesService = inject(CategoriesService);
categories: Category[] = [];
loading = signal(false);
form = this.fb.nonNullable.group({
transactionName: ['', [Validators.required, Validators.minLength(2)]],
transactionType: ['income'],
transactionAmount: ['', [Validators.required, Validators.min(0.01)]],
transactionCategory: ['', [Validators.required]],
transactionDate: ['', [Validators.required]],
transactionDescription: [''/*, [Validators.required, Validators.maxLength(200)]*/],
});
onSubmit(): void {
if (this.form.invalid) {
this.form.markAllAsTouched();
return;
}
this.loading.set(true);
const formValue = this.form.getRawValue();
const payload = {
name: formValue.transactionName,
type: formValue.transactionType,
amount: Number(formValue.transactionAmount),
category: formValue.transactionCategory,
completedAt: formValue.transactionDate,
description: formValue.transactionDescription
};
this.transactionsService.createTransaction(payload).subscribe({
next: (transaction) => {
this.transactionCreated.emit(transaction);
this.form.reset({
transactionName: '',
transactionType: 'income',
transactionAmount: '',
transactionCategory: '',
transactionDate: '',
transactionDescription: '',
});
this.loading.set(false);
},
error: (error) => {
console.error('Error creating transaction: ', error);
this.loading.set(false);
}
});
}
ngOnInit(): void {
this.loadCategories();
}
loadCategories(): void {
this.loading.set(true);
this.categoriesService.getCategories().subscribe({
next: (data) => {
this.categories = data;
this.loading.set(false);
},
error: (error) => {
console.error('Error loading categories:', error);
this.loading.set(false);
},
});
}
}
transaction.ts (TransactionService)
import { HttpClient } from '@angular/common/http';
import { inject, Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Transaction } from '../models/transaction.model';
@Injectable({
providedIn: 'root',
})
export class TransactionsService {
private readonly apiUrl = 'http://localhost:3000/transactions';
private readonly http = inject(HttpClient);
getTransactions(): Observable<Transaction[]> {
return this.http.get<Transaction[]>(this.apiUrl);
}
createTransaction(
data: {
name: string,
type: string,
amount: number,
category: string,
completedAt: string,
description: string,
}
): Observable<Transaction> {
return this.http.post<Transaction>(this.apiUrl, data);
}
}
transaction-list.html
<table class="transactions-table">
<thead>
<tr>
<th>Názov</th>
<th>Typ</th>
<th>Suma</th>
<th>Kategória</th>
<th>Zrealizovaná dňa</th>
<th>Popis</th>
</tr>
</thead>
<tbody>
@for (t of transactions; track t.amount) {
<tr>
<td>{{ t.name }}</td>
<td>
<span [ngClass]="t.type">
{{ t.type === 'income' ? 'Príjem' : 'Výdavok' }}
</span>
</td>
<td>{{ t.amount }} €</td>
<td>{{ t.category }}</td>
<td>{{ t.completedAt | date: 'dd. MM. yyyy' }}</td>
<td>{{ t.description }}</td>
</tr>
}
</tbody>
</table>
解决方案
我修好了。我把状态放在组件中,而不是放在服务里
// transaction.ts (service)
import { HttpClient } from '@angular/common/http';
import { inject, Injectable, signal } from '@angular/core';
import { Observable, tap } from 'rxjs';
import { Transaction } from '../models/transaction.model';
@Injectable({
providedIn: 'root',
})
export class TransactionsService {
private readonly apiUrl = 'http://localhost:3000/transactions';
private readonly http = inject(HttpClient);
private readonly _transactions = signal<Transaction[]>([]);
readonly transactions = this._transactions.asReadonly();
private readonly _loading = signal(false);
readonly loading = this._loading.asReadonly();
getTransactions() {
this._loading.set(true);
return this.http.get<Transaction[]>(this.apiUrl).pipe(
tap({
next: (data) => {
this._transactions.set(data);
this._loading.set(false);
},
error: () => this._loading.set(false)
})
);
}
createTransaction(transaction: Partial<Transaction>) {
return this.http.post<Transaction>(this.apiUrl, transaction).pipe(
tap(newTransaction => {
this._transactions.update(prev => [...prev, newTransaction]);
})
);
}
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。