html - OnInit 列表不显示
问题描述
我正在创建一个 Angular6 crud 应用程序,并且我的数据库中有一个用户列表。我可以在调用 getAllUsers 时检索我的列表,但它不会显示在 UI 中。我唯一一次看到表中显示一行是当我手动输入一个新用户但它不显示我输入之前的数据时。我究竟做错了什么?
import { Component, OnInit } from '@angular/core';
import { UserDataService } from './user-data.service';
import { User } from './user';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [UserDataService]
})
export class AppComponent implements OnInit{
users: User[]=[];
constructor(private userDataService: UserDataService) {}
public ngOnInit() {
debugger
this.userDataService
.getAllUsers()
.subscribe(
(users) => {
this.users = users;
}
);
}
onAddUser(user) {
this.userDataService
.addUser(user)
.subscribe(
(newUser) => {
this.users = this.users.concat(newUser);
}
)
}
onRemoveUser(user){
this.userDataService
.deleteUserById(user.id)
.subscribe(
(_) => {
this.users = this.users.filter((u) => u.id !== user.id);
}
);
}
getUser() {
return this.userDataService.getAllUsers();
}
}
应用程序组件 HTML
<app-user-list-header (add)="onAddUser($event)"></app-user-list-header>
<table>
<th>ID</th>
<th>NAME</th>
<tr *ngFor = "let user of users">
<td>{{user.id}}</td>
<td>{{user.userName}}</td>
</tr>
</table>
用户数据服务
import { Injectable } from '@angular/core';
import { User } from './user';
import { ApiService } from './api.service';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class UserDataService {
constructor(private api: ApiService) { }
addUser(user: User): Observable<User> {
return this.api.createUser(user);
}
getAllUsers(): Observable<User[]> {
return this.api.getAllUsers();
}
updateUser(user: User): Observable<User> {
return this.api.updateUser(user);
}
getUserById(userId: number): Observable<User> {
return this.api.getUserById(userId);
}
deleteUserById(userId: number): Observable<User> {
return this.api.deleteUserById(userId);
}
}
用户列表标题
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { User } from '../user';
@Component({
selector: 'app-user-list-header',
templateUrl: './user-list-header.component.html',
styleUrls: ['./user-list-header.component.css']
})
export class UserListHeaderComponent implements OnInit {
newUser: User = new User();
@Output()
add: EventEmitter<User> = new EventEmitter();
constructor() { }
ngOnInit() {
}
addUser() {
this.add.emit(this.newUser);
this.newUser = new User();
}
}
用户列表标题 HTML
<header class="userHeader">
<h1>Users</h1>
<input class="new-user" placeholder="Enter User" autofocus="" [(ngModel)]="newUser.userName" (keyup.enter)="addUser()">
</header>
API服务
import { Injectable } from '@angular/core';
import { environment } from '../environments/environment';
import { User } from './user';
import { Http } from '@angular/http';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map, catchError } from "rxjs/operators";
const API_URL = environment.apiUrl;
@Injectable({
providedIn: 'root'
})
export class ApiService {
constructor(private http: HttpClient) {
}
public createUser(user: User): Observable<User> {
const headers = {headers: new HttpHeaders({
'Content-Type': 'application/json'
})};
return this.http
.post(API_URL + '/users', user).pipe(
map(response => {
return new User(response);
}), catchError(this.handleError)
)
}
public getAllUsers(): Observable<User[]> {
return this.http
.get(API_URL + '/users').pipe(
map(response => {
var users = [response];
return users.map((user)=> new User(user));
}), catchError(this.handleError))
}
解决方案
问题是,在您之前完成之后,您不需要再次在 AppComponent 中为新用户订阅 observable:
.subscribe(
(newUser) => {
this.users = this.users.concat(newUser);
}
)
因为它已经通过这种方式添加到用户数组中:this.userDataService.addUser(user)
,这表示您向观察者插入了两次相同的值。
因此,您需要做的是,在 userdata 服务中,将观察者插入到其余 api 中,该 api 定期将数据获取到适配器getAllUsers
,如下所示:
getAllUsers(): Observable<user[]> {
// some intermediate post call happens here
this.api.getAllUsers().subscribe((users) => users.map((user)=>this.users.push(user)));
return of(this.users);
}
每当有新值添加到用户群或从 rest 调用通过管道传输时,这将更新用户的状态,因此您不必从同一个观察者多次订阅相同的值,这将导致数据重复。
我找不到允许 post call 的在线 api,因此您可以轻松地使用您自己的工具来计算我上面所说的,但是对于同域 GET api 服务,我在这个术语中做了一个您可以看到的示例这里:
https://stackblitz.com/edit/angular-rndqsd。为了词汇量,将国家作为用户。
推荐阅读
- visual-studio-2015 - 收到错误:Visual Studio 2015 中的“代码执行无法继续,因为找不到 hdf5.dll”
- java - Java8 流:从两个命令对象列表中过滤数据。我在做什么还有其他有效的方法吗?
- node.js - 无法使用 nodeJS 从表中检索数据。错误:ORA-12560:TNS:协议适配器错误
- css - 如何对齐图片前面的文字
- ionic-framework - JIRA API 的离子 CORS 问题
- php - 只获取第一个条目 php mysql
- python - 将 Pandas 数据框转换为字典
- c# - XAML 应用程序抛出 .Net System.Windows.Markup.XamlParseException
- python - 集成 Python 和 C++ MacOS PyModuleDef_HEAD_INIT 未声明
- mongodb - 使用 Java 中的自定义 CodecProvider 反序列化来自 mongodb 的日期会产生空结果