【问题标题】:Angular 4 asynchronous initialization of a service based on a window event基于窗口事件的服务的Angular 4异步初始化
【发布时间】:2018-04-03 04:10:37
【问题描述】:

我正在尝试通过创建一个 web3 服务来将 Web3 与 Angular 4 正确集成,该服务需要等待窗口加载后才能检查 window.web3 是否被注入。我们应该只有在完成后才能查询此服务。以下是 Metamask 文档 excerpt 中的相关代码:

window.addEventListener('load', function() {

  // Checking if Web3 has been injected by the browser (Mist/MetaMask)
  if (typeof web3 !== 'undefined') {
    // Use Mist/MetaMask's provider
    window.web3 = new Web3(web3.currentProvider);
  } else {
    console.log('No web3? You should consider trying MetaMask!')
    // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
    window.web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
  }

  // Now you can start your app & access web3 freely:
  startApp()

})

我发现 this other answer 似乎可以做我想做的事,但是将 Promise 转换为 Observable。

我如何初始化一个包裹这个 web3 对象的 Angular4 服务,以使对 web3 成员的任何请求都将等待它被初始化?

现在我使用的代码使用间隔,但我不喜欢它,因为它感觉很乱。

【问题讨论】:

    标签: angular asynchronous rxjs web3js


    【解决方案1】:

    在你引导你的主模块之后,你会得到一个主模块的实例,其中包含注入器的实例,Angular 将使用它来实例化你的提供程序。因此,您可以获取该实例并将其存储在某处,然后使用它来实例化提供程序。

    假设您想将应用的注入器存储在 app-injector.ts 中,如下所示,

    //app-injector.ts
    
    import { Injector } from '@angular/core';
    
    let appInjectorRef: Injector;
    
    export const appInjector = (injector?: Injector): Injector => {
        if (!injector) {
            return appInjectorRef;
        }
    
        appInjectorRef = injector;
    
        return appInjectorRef;
    };
    

    在您的主模块的引导程序中可能看起来像,

    platformBrowserDynamic()
      .bootstrapModule(TopLevelModule)
      .then((appRef: any) => {
        appInjector(appRef['injector']); // grab the injector instance and store.
      })
      .catch((err) => console.error(err));
    

    接下来,例如在您的 AppComponent 中,您可以这样做,

    import {appInjector} from './app-injector';
    export class AppComponent implements OnInit {
         private service: ServiceThatUsesWeb3;
    
         ngOnInit(): void {
            //.. do web3 instantiation stuffs.
            setTimeout(() => {
              service = appInjector().get(ServiceThatUsesWeb3);
              // use the service.
            });
         }
    }
    

    请注意 setTimeout() 很重要,否则 appInjector() 将返回 undefined。

    【讨论】:

      猜你喜欢
      • 2016-07-23
      • 2017-08-19
      • 1970-01-01
      • 2018-03-31
      • 2015-09-15
      • 2013-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多