Javascript 在angular 2中,在http调用之后返回热/共享可观察对象的最佳方式是什么
这是我的第一篇文章,所以我希望我做的事情是正确的 我试图找到一种最佳方法,既可以使用解析器,又可以在子路由组件及其父路由组件之间共享状态 我有一个Angular 2应用程序,它有一个组件/路由结构,包含一个父路由和两个子路由,如下面的代码示例所示: 路线: 在加载父路由视图和后续子路由视图之前,我正在父路由上使用解析器获取一些数据。数据从进行api调用的服务获取 解析程序: 我想在所有三个组件之间共享person对象的状态,并且不能使用@Input/@Output变量,因为子路由是动态加载到父路由器出口的 以下代码显示解析后订阅ReplaySubject的父组件和子组件之一: 父组件:Javascript 在angular 2中,在http调用之后返回热/共享可观察对象的最佳方式是什么,javascript,angular,rxjs,Javascript,Angular,Rxjs,这是我的第一篇文章,所以我希望我做的事情是正确的 我试图找到一种最佳方法,既可以使用解析器,又可以在子路由组件及其父路由组件之间共享状态 我有一个Angular 2应用程序,它有一个组件/路由结构,包含一个父路由和两个子路由,如下面的代码示例所示: 路线: 在加载父路由视图和后续子路由视图之前,我正在父路由上使用解析器获取一些数据。数据从进行api调用的服务获取 解析程序: 我想在所有三个组件之间共享person对象的状态,并且不能使用@Input/@Output变量,因为子路由是动态加载到父路
导出类MyDetailsComponent实现OnInit{
私人:个人;
私人认购:认购;
构造函数(私有路由:ActivatedRoute,私有personService:personService,私有modalService:NgbModal){
this.route.data.subscribe((obs:Observable)=>{
控制台日志(obs);
this.subscription=obs['person'].订阅(person=>{
这个人=人;
})
},
错误=>{
log('Home Component-Init person error:'+error);
});
}
子组件:
导出类MyDetailsOverviewComponent实现OnInit{
私人:个人;
私人认购:认购;
isReady:boolean=false;
构造函数(专用路由:ActivatedRoute){
this.route.parent.data.subscribe((obs:Observable)=>{
this.person=obs['person'];
this.subscription=obs['person'].订阅(person=>{
这个人=人;
});
});
}
我的想法是在服务中有一个update方法,每个组件都可以调用它。update方法应该在内部调用this.currentPerson.next(newPerson),然后应该通知同级子组件和父组件彼此引起的更改
我的问题是,这是否是一种在父路由和子路由之间共享状态的糟糕方法?是否有其他方法可以做到这一点。目前,我认为我正在泄漏父路由和子路由组件中的订户,在另一个组件中进行订阅调用感觉不好,如下所示:
this.route.data.subscribe((obs: Observable<Person>) => {
console.log(obs);
this.subscription = obs['person'].subscribe(person => {
this.person = person;
})
this.route.data.subscribe((obs:Observable)=>{
控制台日志(obs);
this.subscription=obs['person'].订阅(person=>{
这个人=人;
})
谢谢。是的,在订阅内订阅订阅是noobish。请改用flatmap 一些代码需要消化
public tagsTextStream = this.tagsTextSubject.asObservable().flatMap((q: string) => {
// noinspection UnnecessaryLocalVariableJS
let restStream = this.restQueryService.getTagsList(q)
.map((tags: any) => {
// filter out any tags that already exist on the document
let allTags = _.map(tags, 'name');
let documentTags = _.map(this.tags, 'name');
return _.pull(allTags, ...documentTags);
})
.catch((err: any) => {
return Observable.throw(err);
});
return restStream;
}).publish().refCount();
是的,订阅是noobish。请改用flatmap 一些代码需要消化
public tagsTextStream = this.tagsTextSubject.asObservable().flatMap((q: string) => {
// noinspection UnnecessaryLocalVariableJS
let restStream = this.restQueryService.getTagsList(q)
.map((tags: any) => {
// filter out any tags that already exist on the document
let allTags = _.map(tags, 'name');
let documentTags = _.map(this.tags, 'name');
return _.pull(allTags, ...documentTags);
})
.catch((err: any) => {
return Observable.throw(err);
});
return restStream;
}).publish().refCount();
看起来您正在使用
this.currentPerson.next(person);
在extractPersonData()
中为服务上的“currentPerson”设置一个可观察的对象
通常,需要该用户的组件将订阅PersonService.currentPerson
:)
如果这回答了问题,我不是100%,如果不是,请告诉我,我会尽力帮助您!看起来您正在使用
this.currentPerson.next(person);
在extractPersonData()
中为服务上的“currentPerson”设置一个可观测值
通常,需要该用户的组件将订阅PersonService.currentPerson
:)
如果这回答了问题,我不是100%,如果不是,请告诉我,我会尽力帮助!谢谢大家
我想我已经把事情解决了,所以他们的生活更整洁了
我仍然订阅route.data,但现在我将components internal person对象设置为Observable类型,并使用异步管道来组成“哑”子组件
这就是家长:
export class PersonResolver implements Resolve<any> {
constructor(private personService: PersonService) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): any {
let id: string = route.params['id'];
return this.personService.getPerson(id);
}
}
导出类PersonResolver实现解析{
构造函数(私有personService:personService){}
解析(路由:ActivatedRouteSnapshot,状态:RouterStateSnashot):任意{
let id:string=route.params['id'];
返回此.personService.getPerson(id);
}
}
下面是子路由组件:
export class UpdateMyDetailsComponent implements OnInit {
private person: Observable<Person>;
private subscription: Subscription;
constructor(private route: ActivatedRoute) {
this.route.parent.data.subscribe((result: Observable<Person>) => {
this.person = result['person'];
});
}
导出类UpdateMyDetailsComponent实现OnInit{
私人:可观察;
私人认购:认购;
构造函数(专用路由:ActivatedRoute){
this.route.parent.data.subscribe((结果:可观察)=>{
this.person=结果['person'];
});
}
以下是子路由视图/模板:
<div class="hidden-xs-down">
<div class="row">
<div class="card offset-sm-2 col-sm-3">
<div class="card-title">
<h4>Personal Details</h4>
</div>
<update-personal-details class="card-block" [person]="person | async"></update-personal-details>
</div>
<div class="card offset-sm-1 col-sm-3">
<div class="card-title">
<h4>Contact Details</h4>
</div>
<update-contact-details class="card-block" [person]="person | async"></update-contact-details>
</div>
</div>
<br />
<div class="row">
<div class="card offset-sm-2 col-sm-7">
<div class="card-title">
<h4>Address Details</h4>
</div>
<update-address-details class="card-block" [person]="person | async"></update-address-details>
</div>
</div>
</div>
个人资料
联系方式
地址详情
基本解析逻辑可以保持不变:
@Injectable()
export class PersonResolver implements Resolve<Observable<Person>> {
constructor(private personService: PersonService) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Person> {
let id: string = route.params['id'];
return this.personService.getPerson(id);
}
}
@Injectable()
导出类PersonResolver实现解析{
构造函数(私有personService:personService){}
解析(路由:ActivatedRouteSnapshot,状态:RouterStateSnashot):可观察{
let id:string=route.params['id'];
返回此.personService.getPerson(id);
}
}
我认为这是正确的方法。让我在所有组件之间共享可观察状态,我应该能够通过调用共享可观察状态下一步的服务触发更新等
希望这能帮助那些在类似结构中游手好闲的人
谢谢大家的回答
如果有人认为这是错误的方法,欢迎批评!谢谢大家
我想我已经把事情解决了,所以他们的生活更整洁了
我仍然订阅route.data,但现在我将components internal person对象设置为Observable类型,并使用异步管道来组成“哑”子组件
这就是家长:
export class PersonResolver implements Resolve<any> {
constructor(private personService: PersonService) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): any {
let id: string = route.params['id'];
return this.personService.getPerson(id);
}
}
导出类PersonResolver实现解析{
骗局
export class PersonResolver implements Resolve<any> {
constructor(private personService: PersonService) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): any {
let id: string = route.params['id'];
return this.personService.getPerson(id);
}
}
export class UpdateMyDetailsComponent implements OnInit {
private person: Observable<Person>;
private subscription: Subscription;
constructor(private route: ActivatedRoute) {
this.route.parent.data.subscribe((result: Observable<Person>) => {
this.person = result['person'];
});
}
<div class="hidden-xs-down">
<div class="row">
<div class="card offset-sm-2 col-sm-3">
<div class="card-title">
<h4>Personal Details</h4>
</div>
<update-personal-details class="card-block" [person]="person | async"></update-personal-details>
</div>
<div class="card offset-sm-1 col-sm-3">
<div class="card-title">
<h4>Contact Details</h4>
</div>
<update-contact-details class="card-block" [person]="person | async"></update-contact-details>
</div>
</div>
<br />
<div class="row">
<div class="card offset-sm-2 col-sm-7">
<div class="card-title">
<h4>Address Details</h4>
</div>
<update-address-details class="card-block" [person]="person | async"></update-address-details>
</div>
</div>
</div>
@Injectable()
export class PersonResolver implements Resolve<Observable<Person>> {
constructor(private personService: PersonService) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Person> {
let id: string = route.params['id'];
return this.personService.getPerson(id);
}
}