(我正在重构我的问题,因为我认为第一个问题非常令人困惑......)
我正试图了解Observables如何在Angular 2/4中工作。具体来说,我想在组件初始化时订阅服务的Observable,稍后在组件的生命周期中我想要在没有它的情况下修改数据影响可观察或其他订户。我将数据存储在组件的变量中,但是当我修改它时,Observable的其他订阅者也会显示更改。
在我的代码中有三个可观察对象:客户端,项目和用户。现在我只是想修改项目Observable中的数据。我正在使用数据作为ng2-ui自动完成的来源,所以我不能像下面的评论中所建议的那样使用* ngFor。
common.service.ts(创建可观察的)
import { Observable } from 'rxjs'
import { BehaviorSubject } from 'rxjs';
export class UserService {
public clients: BehaviorSubject<any> = new BehaviorSubject(null);
public projects: BehaviorSubject<any> = new BehaviorSubject(null);
public user: BehaviorSubject<any> = new BehaviorSubject(null);
constructor(){};
}
login.ts(订阅Observable,从API获取数据,然后将其传递给Observables)
ngOnInit() {
this.userService.clients.subscribe();
this.userService.projects.subscribe();
}
userLogin() {
this.commonService.request('login', 'post', '', {password: this.password, email: this.email})
.then((response:any) => {
if(response.token) {
this.configService.token = response.token;
if(response.clients) this.userService.clients.next(response.clients);
if(response.projects) this.userService.projects.next(response.projects);
this.configService.loggedIn = true;
this.router.navigate(['dashboard']);
}
})
}
component.ts(订阅,从Observable获取数据然后修改它。)
ngOnInit() {
this.userService.clients.subscribe((clients) => {
this.clients = clients;
});
this.userService.projects.subscribe((projects) => {
this.projects = projects;
});
this.filteredProjects = this.projects;
this.filteredClients = this.clients;
}
filterProjects(client) { // When a client is selected
this.filteredProjects.forEach((project) => {
if(client.projects.indexOf(project._id) == -1) {
filteredProjects.splice(project._id, 1) // this splices the filteredProjects array, but also this.projects and any other subscriptions to the observable in the app.
}
});
}
当我过滤this.filteredProjects时,this.projects也会被修改。我可以通过两个对象的console.log看到这一点,也因为另一个组件订阅了可观察的项目,而另一个组件也显示了这些更改。
但是,如果我不过滤this.filteredProjects,而只是说this.filteredProjects = [];
,那么this.projects保持不变。
如何在不影响observable或其他订阅者的情况下修改observable中的数据?
答案 0 :(得分:0)
我不完全确定你通过查看你的代码想要实现什么,但是我可能会试着给你一个更好的方向来实现你想要做的事情。
根据我的理解,您需要一个包含项目的通用可观察对象。我假设你已经有了这个工作(尽管你的代码中没有这个)。 现在,在您的组件中,您希望首先订阅它。有几种方法可以使用订阅,我认为你尝试做的方式是订阅它,这种方法的问题是它会带你做很多工作。首先,您需要对项目数组的副本进行处理,因为您现在已经说过要更改所有代码中的项目,因为您的工作与所有相同项目数组的引用(有获取副本的方法的数量,其中一个想到的是使用带有空数组的concat。)
在你这样做之后,你还需要知道用户选择了哪个客户端,所以当再次发出订阅时(我假设项目列表可以在此组件之外更改),你将拥有再次获取新副本然后再次过滤。这可能有效,并且最接近你描述的内容。
我认为您还应该寻找更好的方法,例如在html中使用带有异步管道的ngFor来迭代订阅中的项目 (async pipe, can be used with ngfor。接下来您可以使用html中的自定义过滤器来过滤所选客户端的结果。