1. ホーム
  2. javascript

バックエンドからレンダリングされたパラメータをangular2 bootstrapメソッドに渡す方法

2023-09-26 06:11:05

質問

バックエンドでレンダリングされた引数をangular2 bootstrapのメソッドに渡す方法はありますか?私は、すべてのリクエストに対して ベースリクエストオプション を使用して、バックエンドから提供される値で、すべてのリクエストのためにhttpヘッダを設定したいです。私の main.ts ファイルはこのようになります。

import { bootstrap } from '@angular/platform-browser-dynamic';
import { AppComponent } from "./app.component.ts";

bootstrap(AppComponent);

この引数をルートコンポーネント( https://stackoverflow.com/a/35553650/3455681 ) に渡す方法を見つけましたが、これは bootstrap メソッドを起動するときに必要です... 何かアイデアはありますか?

を編集してください。

webpack.config.jsの内容です。

module.exports = {
  entry: {
    app: "./Scripts/app/main.ts"
  },

  output: {
    filename: "./Scripts/build/[name].js"
  },

  resolve: {
    extensions: ["", ".ts", ".js"]
  },

  module: {
    loaders: [
      {
        test: /\.ts$/,
        loader: 'ts-loader'
      }
    ]
  }
};

どのように解決するのですか?

更新2

プランカーの例

更新 AoT

AoT で動作させるには、ファクトリークロージャーを移動させる必要があります。

function loadContext(context: ContextService) {
  return () => context.load();
}

@NgModule({
  ...
  providers: [ ..., ContextService, { provide: APP_INITIALIZER, useFactory: loadContext, deps: [ContextService], multi: true } ],

参照 https://github.com/angular/angular/issues/11262

更新 RC.6と2.0.0最終版の例

function configServiceFactory (config: ConfigService) {
  return () => config.load();
}

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule,
        routes,
        FormsModule,
        HttpModule],
    providers: [AuthService,
        Title,
        appRoutingProviders,
        ConfigService,
        { provide: APP_INITIALIZER,
          useFactory: configServiceFactory
          deps: [ConfigService], 
          multi: true }
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

初期化の完了を待つ必要がない場合は、`class AppModule {}のコンストラクタも使用できます。

class AppModule {
  constructor(/*inject required dependencies */) {...} 
}

ヒント (循環的依存関係)

例えばルータをインジェクトすると、周期的な依存関係が発生することがあります。 これを回避するために、ルータに Injector を注入し、依存関係を

this.myDep = injector.get(MyDependency);

を注入する代わりに MyDependency のように直接注入します。

@Injectable()
export class ConfigService {
  private router:Router;
  constructor(/*private router:Router*/ injector:Injector) {
    setTimeout(() => this.router = injector.get(Router));
  }
}

更新

これは RC.5 でも同じように動作するはずですが、代わりにプロバイダを providers: [...] の代わりにルートモジュールの bootstrap(...)

に変更しました (まだ自分でテストしていません)。

更新

これを完全にAngularの内部で行う興味深いアプローチが、ここで説明されています。 https://github.com/angular/angular/issues/9047#issuecomment-224075188

を使用することができます。 APP_INITIALIZER を使うことができます。 アプリが初期化されたときに関数を実行し、その関数がプロミスを返した場合、提供するものを遅らせます。 を返す場合は、提供するものを遅らせます。つまり、アプリはそれほど遅延なく初期化することができます。 これは、アプリがそれほどレイテンシなく初期化でき、既存のサービスやフレームワークの機能も利用できることを意味します。 の機能を利用することができます。

例として、マルチテナントのソリューションがあり、サイト情報が提供元のドメイン名に依存しているとします。 サイト情報が提供されるドメイン名に依存しているとします。この場合 これは、[name].letterpress.com または完全なホスト名で一致するカスタム ドメインです。 フルホスト名でマッチングされます。これがプロミスの背後にあることを隠すには、次のようにします。 を使っています。 APP_INITIALIZER .

bootstrapでは。

{provide: APP_INITIALIZER, useFactory: (sites:SitesService) => () => sites.load(), deps:[SitesService, HTTP_PROVIDERS], multi: true}),

sites.service.ts。

@Injectable()
export class SitesService {
  public current:Site;

  constructor(private http:Http, private config:Config) { }

  load():Promise<Site> {
    var url:string;
    var pos = location.hostname.lastIndexOf(this.config.rootDomain);
    var url = (pos === -1)
      ? this.config.apiEndpoint + '/sites?host=' + location.hostname
      : this.config.apiEndpoint + '/sites/' + location.hostname.substr(0, pos);
    var promise = this.http.get(url).map(res => res.json()).toPromise();
    promise.then(site => this.current = site);
    return promise;
  }

注意 config は単なるカスタム設定クラスです。 rootDomain'.letterpress.com' この例では aptaincodeman.letterpress.com .

任意のコンポーネントやその他のサービスに Site を注入できるようになりました。 を注入し .current プロパティを使用します。 を使用することで、アプリ内で待機する必要のない具体的なオブジェクトが生成されます。

このアプローチにより、大きなAngularバンドルの待ち時間で顕著だった起動時のレイテンシーが削減されたように思います。 大きなAngularバンドルのロードを待ち、ブートストラップの前に別のhttpリクエストを待っていた場合、かなり顕著であった起動時の待ち時間を削減するように見えました。 をロードし、ブートストラップが始まる前に別の http リクエストを待っている場合、他の方法ではかなり顕著であった起動の待ち時間を削減するように見えました。

オリジナル

Angularsの依存性注入を使って渡すことができます。

var headers = ... // get the headers from the server

bootstrap(AppComponent, [{provide: 'headers', useValue: headers})]);

class SomeComponentOrService {
   constructor(@Inject('headers') private headers) {}
}

または、用意された BaseRequestOptions のように直接指定することもできます。

class MyRequestOptions extends BaseRequestOptions {
  constructor (private headers) {
    super();
  }
} 

var values = ... // get the headers from the server
var headers = new MyRequestOptions(values);

bootstrap(AppComponent, [{provide: BaseRequestOptions, useValue: headers})]);