我正在编写一个示例应用程序,我有一个用户列表组件:
@Component({
selector: 'user-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.css'],
})
export class ListComponent implements OnInit {
users: Array<User> = [];
private usersService: UsersService;
constructor(private service: UsersService) {
this.usersService = service;
}
loadUsers() {
this.usersService.getUsers().subscribe(users => this.users = users);
}
ngOnInit() {
this.loadUsers();
this.usersService.userEvent.subscribe(user => this.loadUsers());
}
}
服务是:
@Injectable()
export class UsersService {
userEvent: EventEmitter<User> = new EventEmitter();
constructor(private http: Http) {
}
getUsers(): Observable<User[]> {
return this.http.get('/rest/users')
.map(res => res.json());
}
create(user: User) {
this.http.post("/rest/users", user).subscribe(resp => this.userEvent.emit(user));
}
}
export class User {
constructor(public username: string,
public email: string, public password: string
) { }
}
并且有一个用于创建用户的兄弟组件:
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.css']
})
export class FormComponent implements OnInit {
private usersService: UsersService;
constructor(private service: UsersService, private router: Router) {
this.usersService = service;
}
ngOnInit() {
}
onSubmit(formValue: any) {
let user = new User(formValue.username, formValue.email, formValue.password);
this.usersService.create(user);
this.router.navigate(['users']);
}
}
这目前正在做我想做的事情,但我想知道在兄弟组件在服务器上创建新用户的情况下是否有更优雅的方式来更新用户列表。如果我订阅用户列表,则必须使用事件发射器发出信号似乎很奇怪,尽管我也不知道如何通知http.get有关在服务器上创建新用户的信息。
您可以使用BehaviorSubject
通知任何订阅它的组件。这是一种特殊类型的可观察物。例如,在您的用户服务中,定义用户(您可以轻松地将其更改为用户列表):
import {Observable, BehaviorSubject} from 'rxjs/Rx'; //
import {User} from "../../models/user"; // Your model
... inside your class:
private _currentUser = new BehaviorSubject<User>(new User);
getUser = this._currentUser.asObservable();
setUser(user: User) { this._currentUser.next(user) }
在组件中,您可以订阅getUser
主题,如下所示:
this.userService.getUser.subscribe(
user => {
this.user = user;
});
这样,多个组件可以订阅此BehaviorSubject
,并且任何使用setUser
方法的组件/服务中的任何触发器都可以立即更改这些订阅组件。
... you successfully added a user in your
... component, now use the trigger:
this.userService.setUser(this.user);
这是我的库RxCache旨在管理的确切类型。它会为您处理所有可观察的订阅,这样您就不必管理任何订阅或担心订阅泄漏。
https://github.com/adriandavidbrand/ngx-rxcache
在组件中,您可以公开用户的可观察量和加载标志。
@Component({
selector: 'user-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.css'],
})
export class ListComponent implements OnInit {
users$ = this.service.users$;
loading$ = this.service.loading$;
constructor(private service: UsersService) {
service.load();
}
}
在HTML中使用异步管道来管理所有订阅
<div *ngIf="loading$ | async else elseBlock">loading ...</div>
<ng-template #elseBlock>
<div *ngIf="users$ | async as users">
<div *ngFor="let user of users">
Email: {{user.email}}
</div>
</div>
</ng-template>
在您的服务中使用RxCache安装“npm install ngx-rxcache --save”并从'ngx-rxcache'导入{RxCacheService};
@Injectable()
export class UsersService {
constructor(private http: Http, private cache: RxCacheService) { }
private userCache = this.cache.get<User[]>({
id: '[User] users',
construct: () => this.http.get<User[]>('/rest/users'),
save: user => this.http.post<User[]>("/rest/users", user)
});
users$ = this.userCache.value$;
loading$ = this.userCache.loading$;
saving$ = this.userCache.saving$;
create(user: User, saved?: (response: any, value: any) => void) {
this.userCache.save(user, saved);
}
load() {
this.userCache.load();
}
}
// Use interfaces over classes
export interface User {
username: string;
email: string;
password: string;
}
并在兄弟组件
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.css']
})
export class FormComponent implements OnInit {
constructor(private service: UsersService, private router: Router) { }
saving$ = this.service.saving$;
ngOnInit() {
}
onSubmit(formValue: any) {
let user = { username: formValue.username, email: formValue.email, password: formValue.password };
this.usersService.create(user, (response, value) => {
// Don't navigate until the save has finished.
this.router.navigate(['users']);
});
}
}
在您的html中,您可以像在加载其他组件时一样显示保存消息。
<div *ngIf="saving$ | async">saving ...</div>