Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/461.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在angular 2中,在http调用之后返回热/共享可观察对象的最佳方式是什么_Javascript_Angular_Rxjs - Fatal编程技术网

Javascript 在angular 2中,在http调用之后返回热/共享可观察对象的最佳方式是什么

Javascript 在angular 2中,在http调用之后返回热/共享可观察对象的最佳方式是什么,javascript,angular,rxjs,Javascript,Angular,Rxjs,这是我的第一篇文章,所以我希望我做的事情是正确的 我试图找到一种最佳方法,既可以使用解析器,又可以在子路由组件及其父路由组件之间共享状态 我有一个Angular 2应用程序,它有一个组件/路由结构,包含一个父路由和两个子路由,如下面的代码示例所示: 路线: 在加载父路由视图和后续子路由视图之前,我正在父路由上使用解析器获取一些数据。数据从进行api调用的服务获取 解析程序: 我想在所有三个组件之间共享person对象的状态,并且不能使用@Input/@Output变量,因为子路由是动态加载到父路

这是我的第一篇文章,所以我希望我做的事情是正确的

我试图找到一种最佳方法,既可以使用解析器,又可以在子路由组件及其父路由组件之间共享状态

我有一个Angular 2应用程序,它有一个组件/路由结构,包含一个父路由和两个子路由,如下面的代码示例所示:

路线: 在加载父路由视图和后续子路由视图之前,我正在父路由上使用解析器获取一些数据。数据从进行api调用的服务获取

解析程序: 我想在所有三个组件之间共享person对象的状态,并且不能使用@Input/@Output变量,因为子路由是动态加载到父路由器出口的

以下代码显示解析后订阅ReplaySubject的父组件和子组件之一:

父组件:
导出类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);
    }
}