如何使用服务初始化可注入变量
How do I Initialize Injectable variable using a service
我正在使用 Ionic2 存储在用户登录时存储用户 access_token 凭据。
当用户尝试访问后端时 api 我需要向 REST 客户端提供 access_token。
我使用 hBoylan's ng2-http package 创建了服务
最初包使用
export class CategoryService extends RESTClient{
categoryList : Category[] = [];
public user:User;
constructor(protected http:Http) {super(http)}
}
我已经使用 Angular2 DI 将 UserStorage 组件添加到构造函数中:
let categoryServiceFactory = (http:Http, userStorage:UserStorage) => {
return new CategoryService(http, userStorage);
}
export let categoryServiceProvider =
{
provide: CategoryService,
useFactory: categoryServiceFactory,
deps: [Http, UserStorage]
}
得到这个:
export class CategoryService extends RESTClient{
categoryList : Category[] = [];
public user:User;
constructor(protected http: Http, protected userStorage: UserStorage)
{
super(http);
this.userStorage.getUser().then((data:User) => {this.user = data})
}
目前我打电话的时候
@GET('/itemtype/list')
@Produces<String>()
public getAvailableCategories(): Observable<String> {
return null;
}
我需要使用
protected requestInterceptor(req: Request) {
req.headers.set('Authorization', `Bearer ${this.user.api_credentials.access_token}`)
return req;
}
添加 access_token 凭据
截至目前,我在页面组件中的调用必须如下所示:
@Component({
selector: 'page-categories',
templateUrl: 'categories.html',
providers: [User]
})
export class CategoriesPage implements OnInit {
// list of categories
public categories: any;
constructor(public nav: NavController,
public categoryService: CategoryService,
public userStorage: UserStorage,
public user: User) {}
ngOnInit() {
this.userStorage.getUser().then((user: User) => {
this.user = user
this.categoryService.setUser(this.user);
this.categoryService.getAvailableCategories().subscribe(
(data) => { console.log(data) },
error => console.log(error),
() => { });
});
}
// view category
viewCategory(categoryId) {
this.nav.push(CategoryPage, { id: categoryId });
}
showChildren(category: Category) {
category.open = !category.open;
}
openCategoryPage($event, category: Category) {
$event.stopPropagation();
this.nav.push(CategoryPage, { cat_id: category.id })
}
}
它看起来像这样的原因是因为我似乎无法在 CategoryService 的构造函数中设置用户 class。所以我必须首先从存储中获取用户,在类别服务中使用 "setter",然后将 getAvailableCategories() 调用嵌套在 getUser().then() 函数中。
这是因为在 CategoryService 构造函数完成从 UserStorage 设置用户之前调用了 getCategories 函数。
我知道这是因为调用是异步的,但我觉得好像使用 setTimeout 之类的东西 "wait" 直到 getUser 调用返回是 hacky 并且不是 100% 可靠。
还有什么我可以尝试的吗?我真的很想打电话给
this.categoryService.getAvailableCategories().then()
并从那里继续,没有嵌套的 promise 调用。
我准备进行任何精明的更改,以使 access_token 立即可用。
如果 getUser
调用是异步的,您可以尝试使其同步:)
如果这不是您的选择,这里有一个语法糖可以帮助您以更好的方式处理异步调用 – async/await
:
async ngOnInit() {
this.categories = this.categoryService.getCategories();
this.user = await this.userStorage.getUser();
this.categoryService.setUser(this.user);
this.categoryService.getAvailableCategories().subscribe(
(data) => { console.log(data) },
(error) => { console.log(error) },
() => { }
);
}
注意是 async ngOnInit
然后是 await this.userStorage.getUser()
我正在使用 Ionic2 存储在用户登录时存储用户 access_token 凭据。
当用户尝试访问后端时 api 我需要向 REST 客户端提供 access_token。
我使用 hBoylan's ng2-http package 创建了服务 最初包使用
export class CategoryService extends RESTClient{
categoryList : Category[] = [];
public user:User;
constructor(protected http:Http) {super(http)}
}
我已经使用 Angular2 DI 将 UserStorage 组件添加到构造函数中:
let categoryServiceFactory = (http:Http, userStorage:UserStorage) => {
return new CategoryService(http, userStorage);
}
export let categoryServiceProvider =
{
provide: CategoryService,
useFactory: categoryServiceFactory,
deps: [Http, UserStorage]
}
得到这个:
export class CategoryService extends RESTClient{
categoryList : Category[] = [];
public user:User;
constructor(protected http: Http, protected userStorage: UserStorage)
{
super(http);
this.userStorage.getUser().then((data:User) => {this.user = data})
}
目前我打电话的时候
@GET('/itemtype/list')
@Produces<String>()
public getAvailableCategories(): Observable<String> {
return null;
}
我需要使用
protected requestInterceptor(req: Request) {
req.headers.set('Authorization', `Bearer ${this.user.api_credentials.access_token}`)
return req;
}
添加 access_token 凭据
截至目前,我在页面组件中的调用必须如下所示:
@Component({
selector: 'page-categories',
templateUrl: 'categories.html',
providers: [User]
})
export class CategoriesPage implements OnInit {
// list of categories
public categories: any;
constructor(public nav: NavController,
public categoryService: CategoryService,
public userStorage: UserStorage,
public user: User) {}
ngOnInit() {
this.userStorage.getUser().then((user: User) => {
this.user = user
this.categoryService.setUser(this.user);
this.categoryService.getAvailableCategories().subscribe(
(data) => { console.log(data) },
error => console.log(error),
() => { });
});
}
// view category
viewCategory(categoryId) {
this.nav.push(CategoryPage, { id: categoryId });
}
showChildren(category: Category) {
category.open = !category.open;
}
openCategoryPage($event, category: Category) {
$event.stopPropagation();
this.nav.push(CategoryPage, { cat_id: category.id })
}
}
它看起来像这样的原因是因为我似乎无法在 CategoryService 的构造函数中设置用户 class。所以我必须首先从存储中获取用户,在类别服务中使用 "setter",然后将 getAvailableCategories() 调用嵌套在 getUser().then() 函数中。
这是因为在 CategoryService 构造函数完成从 UserStorage 设置用户之前调用了 getCategories 函数。
我知道这是因为调用是异步的,但我觉得好像使用 setTimeout 之类的东西 "wait" 直到 getUser 调用返回是 hacky 并且不是 100% 可靠。
还有什么我可以尝试的吗?我真的很想打电话给
this.categoryService.getAvailableCategories().then()
并从那里继续,没有嵌套的 promise 调用。
我准备进行任何精明的更改,以使 access_token 立即可用。
如果 getUser
调用是异步的,您可以尝试使其同步:)
如果这不是您的选择,这里有一个语法糖可以帮助您以更好的方式处理异步调用 – async/await
:
async ngOnInit() {
this.categories = this.categoryService.getCategories();
this.user = await this.userStorage.getUser();
this.categoryService.setUser(this.user);
this.categoryService.getAvailableCategories().subscribe(
(data) => { console.log(data) },
(error) => { console.log(error) },
() => { }
);
}
注意是 async ngOnInit
然后是 await this.userStorage.getUser()