1

ASP.NET Core の TypeScript で Angular 2.0.0 を使用しています。私の目標は、サーバー側の変数に基づいて、アプリで AppConfig サービスを作成することです。他のいくつかの回答の助けを借りて、次のコードを作成できました。

インデックス.cshtml

<app>
    <i class="fa fa-spin fa-5x fa-spinner"></i>
</app>

<script>
    System.import('/app/main').then((m) => {
        var config = {
            apiUrl: @options.ApiServerUrl
        };

        m.RunApplication(config);
    }, console.error.bind(console));
</script>

app.config.ts

import { Injectable } from "@angular/core";

@Injectable()
export class AppConfig {
    apiUrl: string;
}

main.ts

import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";

import { AppModule } from "./app.module";
import { AppConfig } from "./app.config";

export function RunApplication(config: Object) {

    var appConfig = new AppConfig();
    appConfig.apiUrl = config["apiUrl"];

    console.log('Created config: ', appConfig);

    platformBrowserDynamic()
        .bootstrapModule(AppModule, [{ providers: [{ provide: AppConfig, useValue: appConfig }] }])
        .catch(err => console.error(err));
}

app.module.ts

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { HttpModule } from "@angular/http";
import { AppRouting, AppRoutingProviders } from "./app.routes";
import { AppConfig } from "./app.config";
import { AppComponent } from "./app.component";
import { DashboardComponent } from "./dashboard/dashboard.component";
import { DashboardService } from "./dashboard/dashboard.service";

@NgModule({
    declarations: [
        AppComponent,
        DashboardComponent
    ],
    imports: [
        BrowserModule,
        HttpModule,
        AppRouting
    ],
    providers: [
        AppRoutingProviders,
        AppConfig,
        DashboardService
    ],
    bootstrap: [AppComponent],
})
export class AppModule { }

dashboard.service.ts

import { Http } from "@angular/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs/Rx";
import "rxjs/add/operator/map";
import { AppConfig } from "../app.config";

@Injectable()
export class DashboardService {

    constructor(private appConfig: AppConfig, private http: Http) {
        console.log('Injected config: ', appConfig);
        console.log('Injected apiUrl: ', appConfig.apiUrl);
    }
}

Chrome コンソールからの出力

Chrome コンソールからの出力

ご覧のとおり、何らかの理由で作成されたものと注入されAppConfigたものは同じではなく、 にapiUrl値が表示されませんDashboardService。エラーはここのどこかにあると思います:

bootstrapModule(AppModule, [{ providers: [{ provide: AppConfig, useValue: appConfig }] }])

しかし、私はAngular2にまったく慣れていないため、修正方法がわかりません。どこに問題があるのか​​教えていただけますか?

4

3 に答える 3

0

オブジェクトをグローバルに追加することになりました。

// ===== ファイル globals.ts

import { AppConfig } from './app.config';
'use strict';
export var appConfig: AppConfig;

// ===== ファイル app.config.ts

import { Injectable } from "@angular/core";
@Injectable()
export class AppConfig {
    entityId: string;
    formId: string;
}

// ===== ファイル index.html または cshtml

<script>
    System.import('app').then((m) => {
        var config = {
            entityId: '12',
            formId: '22'
        };
        m.RunApplication(config);
        },
        console.error.bind(console)
    );
</script>

// ===== ファイル main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';
import { AppConfig } from './app.config';
import myGlobals = require('./globals');

//platformBrowserDynamic().bootstrapModule(AppModule);

export function RunApplication(config: Object) {

    var appConfig = new AppConfig();
    appConfig.entityId = config["entityId"];
    appConfig.formId = config["formId"];

    console.log('Created config: ', appConfig, appConfig.entityId, appConfig.formId);

    myGlobals.appConfig = appConfig;

    platformBrowserDynamic()
        .bootstrapModule(AppModule)
        .catch(err => console.error(err));
}

// ===== ファイル app.module.ts

import { AppConfig } from './app.config';
import myGlobals = require('./globals');
...

@NgModule({
    imports: [
        ...
    ],
    declarations: [
        ...
    ],
    providers: [
        {
            provide: AppConfig,
            useValue: myGlobals.appConfig
        }
    ],
    bootstrap: [AppComponent]
})

// ===== ファイル intro.component.ts

import { AppConfig } from "./app.config";
import myGlobals = require('./globals');
@Component({
    selector: 'my-intro,[my-intro]',
    templateUrl: ''
})
export class IntroComponent {
    constructor() {
        console.log('constructor', 'appConfig', myGlobals.appConfig);
    }
}
于 2016-10-14T00:33:54.157 に答える
0

構成設定をロードする Promise を使用して CanActivate クラスでルートを保護することも機能するはずです。

promise を返すような関数で appSettings.service を使用する

getAppSettings(): Promise<any> {
        var observable = this.http.get(this.ApiUrl, { headers: this.headers })
            .map((response: Response) => {
                var res = response.json();
                return res;
            });

        observable.subscribe(config => {
        this.config= config;
        console.log(this.config)
        });
        return observable.toPromise();  
    }

そして、以下のような CanActivate ガード:

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { AppSettingsService } from './appsettings.service';

@Injectable()
export class CanActivateViaAuthGuard implements CanActivate {

//router: Router
    constructor(private appSettingsService: AppSettingsService)
    {
    }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
               return this.appSettingsService.getAppSettings().then(() => { 
    return true });
   }
}

これにより、対応するコンポーネントが構築されるときに設定が使用可能になります。(APP_INITIALIZER を使用しても呼び出されるコンストラクターが制限されなかったので、この手法を使用する必要がありました。また、エクスポート内のすべてのコンポーネントをエクスポートしないようにしてください:[] モジュール内)

ルートを保護し、コンストラクターが呼び出される前に設定が読み込まれるようにするには、ルート定義のパスで通常の canActivate オプションを使用してください。

 path: 'abc',
 component: AbcComponent,
 canActivate: [CanActivateViaAuthGuard]

appsettings の初期化は、AbcComponent のコンストラクターが呼び出される前に行われる必要があります。これはテスト済みで、Angular 2.0.1 で動作します。

于 2016-10-20T21:12:47.527 に答える