微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我们要做的是从URL调用一个端点,该URL返回2个变量,这些变量可以在站点的多个部分中使用.尽管我们正在使用http调用订阅它,但是为了加快站点速度,我们只想进行一次api调用.为此,我们在服务上创建了一个Observable.服务调用构造函数中的一个函数,该函数设置Observable的值,但是有时在直接访问链接时会返回无法预订的undefined方法.下面是使用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函数是:

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
    }
  ]
},

解决方法:

问题在于您的公共详细信息:Observable< any&gt ;;没有在开始时初始化,并且在订阅中传递给getToken(),每次通过使用以下命令将其设置为新的Observable

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

因此,您的组件在访问详细信息时将获得不同的对象,具体取决于访问它们的时间点.

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐