首页 文章

以角度2设置可观察变量

提问于
浏览
2

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

Firstly we are setting the variable as an Observable in the service:

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

Then we are setting the observable values in the constructor:

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();
    });
  });
});

The getToken function is:

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

The get function is:

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 is then called in the constructor of the component as follows:

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

这应该添加me endpoints 返回的控制台日志,但是在某些页面上它会执行,而其他页面返回的则无法订阅undefined . 正确地在两个页面上的构造函数中调用并设置MicrosoftGraphService .

我想知道这是否因为它被调用的方式以及何时设置而发生访问基本URL将调用父组件,因为在该构造函数中调用MicrosoftGraphService它首先被初始化,因此在通过导航访问第二个组件时可用 . 但是,直接转到子组件的URL位置可能意味着它在父组件之前首先被调用,即使它们都加载了MicrosoftGraphService .

Example of the routes if it helps:

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

1 回答

  • 3

    问题是您的 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

相关问题