【问题标题】:BehaviorSubject RxJs angular2BehaviorSubject RxJs angular2
【发布时间】:2017-05-04 15:05:01
【问题描述】:

我没有得到带有 BehaviorSubject 的组件中的响应值。我得到它并在服务中传递它。

我正在从路由保护服务触发 HTTP。

服务:

@Injectable()
export class ProjectsService {
projects: Subject<Project[]> = new BehaviorSubject<Project[]>([]);

load(clientId: string, active: boolean): Observable<boolean> {
    return new Observable<boolean>((obs) => {
        this._api.send(active ? 'projects.getActive' : 'projects.getAll',clientId).subscribe(
            res => {
                let temp = [];
                res.forEach(a => temp.push(new Project(a)));

                if (active) this.projects.next(temp);
                else this.externalProjects.next(temp);
                obs.next(true);
                obs.complete();
            },

            err => {
                obs.next(false);
                obs.complete();
            }
        );
    });
}

组件:

ngOnInit(): void {
    // todo: check why not to load already added
    this._projectsListener = this._projectsService.projects.subscribe(a => {
        this.showIntro = a.length ? false : true;
        this.projects = a;
    });
 }

HTML:

<div class="project" [hidden]="!showIntro" *ngFor="let project of projects>
  {{project.title}}
</div>

它只是获取 HTTP 参数的查询参数... 守卫:

@Injectable()
export class ProjectsGuard implements CanActivate {
   constructor(
       private _projectsService: ProjectsService,
       private _router: Router) {}

   canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
       return this._projectsService.load(next.params['id'], true)
   }
}

我也尝试了NgZone,但我不确定它是否正确:

load(clientId: string, active: boolean): Observable<boolean> {
    return this._api.send(active ? 'projects.getActive' : 'projects.getAll',clientId)
        .map(res => {
            let temp = res.map(a => new Project(a));

            this._ngZone.run(() => {
                console.log('temp: ', temp);
                if (active) this.projects.next(temp);
                else this.externalProjects.next(temp);
            });

            return true;
        })
        .catch(() => Observable.of(false));
}

【问题讨论】:

  • 你遇到了什么问题?您可以提及您遇到了什么错误。
  • load() 在哪里调用?为什么要使用这么多嵌套的 observables?
  • 我没有收到错误...只是没有呈现任何数据...无法在组件中获得 HTTP 响应。 load() 在路由保护(canActivate)上被正确调用。

标签: angular rxjs


【解决方案1】:

首先:不要在可观察对象中订阅另一个可观察对象。而是将其写为流:

@Injectable()
export class ProjectsService {
projects: Subject<Project[]> = new BehaviorSubject<Project[]>([]);

load(clientId: string, active: boolean): Observable<boolean> {
    return this._api.send(active ? 'projects.getActive' : 'projects.getAll',clientId)
        .map(res => {
                let temp = res.map(a => new Project(a));

                if (active) {
                    this.projects.next(temp);
                } else {
                    this.externalProjects.next(temp);
                }
                return true;
            })
       .catch(() => Observable.of(false));
}

其次:不要手动订阅无穷无尽的流将结果写入类成员,而是使用async-pipe:

public projects$: Observable<Project[]> = this._projectsService.projects;
public showIntro$: Observable<boolean> = this.projects$
    .map(projects => projects.length > 0);

ngOnInit(): void {
    // ...nothing to do here
}

模板:

<div class="project" [hidden]="!showIntro" *ngFor="let project of (projects$ | async)>
  {{project.title}}
</div>
....somewhere else:
<div *ngIf="showIntro$ | async">INTRO!</div>

如果您的加载问题仍然存在,那么您可能希望共享 api.send 方法的内容(除非确实调用了该方法)。

一种可能是在 ngZone 之外运行异步方法,然后您可能想尝试以下方法:

【讨论】:

  • 首先,感谢您的努力,谢谢。我尝试了你写的所有东西。关于“在可观察对象中可观察的”,您是对的。我没有提供我在 ngOnDestroy 取消订阅的所有组件代码。 API 很干净,当我 console.log(temp) 在服务中时,我得到了我想要的数据,但没有在我得到一个空数组的组件中。我在控制台中没有错误,所以我不知道该怎么做,任何建议都会帮助我。我不知道这是否无关紧要,但我雄心勃勃地将这个应用程序从 rc6 更新到 4.0.0-beta.0,除了这个 BehaviorSubject 之外,一切都运行良好。
  • 我也尝试NgZone,但不确定它是否正确...检查主帖子编辑...
  • 您只需将 .next 调用包装在 ngZone.run 中 - 应该已经这样做了,不需要多层回调等。 :)
  • 还是不行。我console.log(projects$)在一些随机点击按钮上,所以我提供了一个截图。
  • 我成功让它工作了,但是我需要将包括 angular 在内的一堆包降级到 2.1... 仍然没有得到它是哪个在没有错误的情况下破坏它....跨度>
猜你喜欢
  • 2017-01-22
  • 2021-04-19
  • 1970-01-01
  • 1970-01-01
  • 2019-10-02
  • 2018-08-31
  • 1970-01-01
  • 2018-11-07
  • 2020-09-27
相关资源
最近更新 更多