【发布时间】:2018-05-12 05:33:20
【问题描述】:
我的 Angular 5 项目中有一个服务,它拥有一些配置状态:
@Injectable
export class FooService {
isIncognito: boolean = null;
constructor() {
// I want Angular to wait for this to resolve (i.e. until `isIncognito != null`):
FooService.isIncognitoWindow()
.then( isIncognito => {
this.isIncognito= isIncognito;
} );
}
private static isIncognitoWindow(): Promise<boolean> {
// https://stackoverflow.com/questions/2909367/can-you-determine-if-chrome-is-in-incognito-mode-via-a-script
// https://developer.mozilla.org/en-US/docs/Web/API/LocalFileSystem
return new Promise<boolean>( ( resolve, reject ) => {
let rfs = window['requestFileSystem'] || window['webkitRequestFileSystem'];
if( !rfs ) {
console.warn( "window.RequestFileSystem not found." );
resolve( false );
}
const typeTemporary = 0;
const typePersistent = 1;
// requestFileSystem's callbacks are made asynchronously, so we need to use a promise.
rfs(
/*type: */ typeTemporary,
/* bytesRequested: */ 100,
/* successCallback: */ function( fso: WebKitFileSystem ) {
resolve( false );
},
/* errorCallback: */ function( err: any /* FileError */ ) {
resolve( true );
}
);
} );
}
}
我的项目中的许多组件都使用此服务,并作为构造函数参数传递。例如:
@Component( {
moduleId: module.id,
templateUrl: 'auth.component.html'
} )
export class AuthComponent implements OnInit {
constructor( private fooService: FooService ) {
}
ngOnInit(): void {
// do stuff that depends on `this.fooService.isIncognito != null`
}
}
理想情况下,我希望 Angular 在将 FooService 注入其他组件之前先等待 FooService::isIncognitoWindow() 承诺解决(解决立即发生,但不是同步发生)。
另一种解决方案是将FooComponent.isIncognito 的属性更改为Promise<boolean> 并再次解析它并通过回调调用ngOnInit 的其余部分,但这意味着每个组件都会导致再次调用promise 的主函数- 所以这意味着可能将其更改为缓冲的 Observable 或 Subject ,这变得不必要的复杂 - 所有这些都针对单个 boolean 值。这也意味着重构大量我不想做的代码。
【问题讨论】:
-
您可以在应用程序启动之前使用 APP_INITIALIZER 令牌来解析 isIncognito 值,然后在接下来的值中解析组件/服务
-
@David 这听起来很有希望——你能用一个简短的例子在答案中重新发布吗?这样我就可以接受了。