javascript - 在 Angular 2 中设置可观察变量

标签 javascript angular rxjs angular2-observables

我们想要做的是从 url 调用端点,该 url 返回 2 个变量,可用于站点的多个部分。虽然我们正在使用 http 调用并订阅它,但为了加快站点速度,我们只想进行一次 api 调用。为了做到这一点,我们在服务上创建了一个 Observable。服务在构造函数中调用一个函数来设置 Observable 的值,但是有时直接访问链接时会返回无法订阅未定义的方法。这是使用 Microsoft ADAL 库的示例代码如下:

首先我们将变量设置为服务中的 Observable:

@Injectable()
export class MicrosoftGraphService {
  public details: Observable<any>;

然后我们在构造函数中设置可观察值:

constructor(
private _http:Http,
private _adalService: AdalService,
private _sanitizer:DomSanitizer
) {

this.getToken().subscribe(token => {
  /**
   * Get me data from graph to determine school_id and mis_id
   */
  this.get('me', token, true).subscribe(me => {
    this.details = new Observable(observer => {
        observer.next({
          me: me
        });
        observer.complete();
    });
  });
});

getToken 函数是:

getToken(): Observable<any> {
    return this._adalService
      .acquireToken( this._adalService.config.endpoints.graph );
}

获取函数是:

get( endpoint, token, beta = false ): Observable<any>  {
  return this._http.get( this._adalService.config.endpoints.graph + 
    this.getVersion( beta ) + endpoint, {
      headers: new Headers({ "Authorization": "Bearer " + token })
    })
    .map(res => {
      return res.json();
    });
}

然后在组件的构造函数中调用如下:

this._microsoftGraph.details.subscribe(details => {
    console.log(details);
});

这应该添加 me 端点返回的控制台日志,但是在某些页面上它确实如此,而在其他页面上它返回无法订阅未定义。在两个页面的构造函数中正确调用和设置了 MicrosoftGraphService。

我想知道这是否因为它的调用方式和设置时间而发生,例如访问基本 url 将调用父组件,因为在该构造函数中调用 MicrosoftGraphService 它首先被初始化,因此在通过导航访问第二个组件时可用。但是,直接转到子组件的 URL 位置可能意味着先调用它,然后再调用父组件,即使两者都加载了 MicrosoftGraphService。

路线示例(如果有帮助):

const routes: Routes = [
{
    path: '',
    component: SiteComponent,
canActivate: [LoggedInGuard],
children: [
    { path: 'dashboard', component: DashboardComponent },
    { path: 'tasks', component: TasksComponent },
    {
      path: '',
      redirectTo: '/dashboard'
      , pathMatch: 'full'
      // , terminal: true
    }
  ]
},

最佳答案

问题是你的 public details: Observable<any>;在开始和您传递给 getToken() 的订阅中未初始化您将其设置为新的 Observable每次使用

this.details = new Observable(observer => {
    observer.next({
      me: me
    });
    observer.complete();
});

因此,您的组件在访问 details 时将获得不同的对象,取决于他们访问它的时间点。

我建议在您的服务中执行类似以下操作:

detailsSubject = new Subject<any>();
public details = this.detailsSubject.asObservable();

// --- in your subscription where you set your Observable before
this.detailsSubject.next(/* here comes your token */);

有关更多信息,请查看此 example

关于javascript - 在 Angular 2 中设置可观察变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43516798/

相关文章:

javascript - 验证 FormGroup 中的输入掩码

Angular 2 新路由器 : How to get router parameters of a child component?

javascript - 如何在第二次单击时重置值

javascript - 如何在控制台中将 HTML 元素存储为全局变量

javascript - 使用 JavaScript 在 OnClick 按钮上添加表格行并保存在 Laravel 的数据库中

angular - 如何测试(Jasmine)服务实际处理模拟 HTTP 错误的错误

angular - 如何在 Angular 5 应用程序中正确使用 Angular 百分比管道?

javascript - 如何喂养 rxjs 观察者

javascript - Angular 错误: Webpack has been initialised using a configuration object that does not match the API schem

javascript - HTML5 仍然支持 pixelHeight 吗