问题描述
在我的应用程序中,我使用行为主题来加载数据:
我的服务:
data$ = new BehaviorSubject({
users: [],user: {}
});
constructor();
}
dispatch(action: Action): Observable<true | { error: string; }> {
switch (action.type) {
case ActionTypes.USER_LIST:
this.getUsers();
return of(true);
default:
return of(true);
}
}
private getUsers(){
this.http.get("url")
.subscribe((users: any) => {
this.data$.next({...this.data$.value,users: users});
});
}
当我的子组件请求它时,我会在我的父组件中调用它。
我的父组件:
export class MyParentComponent implements OnInit {
isLoading = false;
user$ = new BehaviorSubject(null);
constructor(private userService: UserService) { }
ngOnInit(): void {
}
getUsers(event) {
this.isLoading = true;
this.userService.dispatch({type: Action Types.USERR_LIST});
this.user$.next(this.userService.data$);
this.isLoading = false;
}
}
MyChildComponent:调用加载数据:
private getData() {
this.onDataChange.emit(this.criteria);
this.dataSource.data = this.items;
console.log(this.dataSource);
this.isLoading = false;
}
调用我的子组件:
<app-child-comp
[entity]="(user$| async)?.value?.userList"
(onDataChange)="getUsers($event)"
class="row col-md-12"
>
</app-child-comp>
我不明白为什么我的数据源或我的 items 属性在 onEmit 之后没有更新,而当我在我的子组件中将 items 属性显示到 json 训练时它是最新的
解决方法
根据您的代码,以下是我将如何实现它,为清晰起见重命名一些内容并键入一些对象:
服务:
export interface DataUsers {
users: User[],user: User
}
data$ = new BehaviorSubject({
users: [],user: {}
});
constructor();
// TODO
}
public dispatch(action: Action): Observable<true | { error: string; }> {
switch (action.type) {
case ActionTypes.USER_LIST:
this.callUsersApi();
return of(true);
default:
return of(true);
}
}
public getDataUsers$(): Observable<DataUsers> {
return this.data$.asObservable();
}
private callUsersApi(): void {
this.http
.get('url')
.subscribe((users: User[]) => {
this.data$.next({...this.data$.value,users: users});
});
}
父组件:
// {...}
export class MyParentComponent implements OnInit {
isLoading = false;
user$: Observable<DataUsers> = null;
constructor(private userService: UserService) {
this.user$ = this.userService.getDataUsers$();
}
ngOnInit(): void {
}
getUsers(event) {
this.isLoading = true;
this.userService.dispatch({type: ActionTypes.USERR_LIST});
// this.user$ will automatically receive the new data
this.isLoading = false;
}
}
父 HTML(更新管道异步):
<app-child-comp
class="row col-md-12"
[entity]="(user$| async)?.userList"
(onDataChange)="getUsers($event)">
</app-child-comp>
子组件:
public ngOnChanges(changes: SimpleChanges) {
if (changes.entity) {
// this.entity has changed
this.isLoading = false;
if (changes.entity.currentValue) {
// the new value is not empty
if (!this.dataSource) {
// init
this.dataSource = new MatTableDataSource(changes.entity.currentValue);
} else {
// update
this.dataSource.data = changes.entity.currentValue;
}
} else {
// the new value is null
if (!this.dataSource) {
// data were displayed,reset them
this.dataSource.data = [];
}
}
}
}
private getData() {
this.isLoading = true;
this.onDataChange.emit(this.criteria);
// you cannot set dataSource here,the HTTP call is not ended yet
// when HTTP call will be ended,the ngOnChanges will be triggered because the parent will inject a new value to this.entity
// so this.isLoading will be falsed in ngOnChanges,not here.
}