17

共有フォルダーに何かを生成するたびに、index.ts ファイルが再構築され、エクスポートがアルファベット順に配置されます。これは私にとって依存関係を壊しているようです。依存関係を持つクラスの前に依存関係がエクスポートされるように手動で順序を変更すると、再び機能します。

私たちが持っている場合app/shared/auth.guard.ts

import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';

import { AuthService, User } from './';

@Injectable()
export class AuthGuard implements CanActivate {

    constructor(private accountService: AuthService, private router: Router) { }

    canActivate(next: ActivatedRouteSnapshot): Observable<boolean> {
        let result = this.accountService.currentUser.first().map(user => user != null);

        let route: any[] = ['/login'];

        if (next.url.length) {
            route.push({ redirectUrl: next.url });
        }

        result.subscribe(isLoggedIn => {
            if (!isLoggedIn) {
                this.router.navigate(route);
            }
        });

        return result;
    }
}

app/shared/account.service.ts:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

import { User } from './';

const LOCAL_STORAGE_KEY = 'currentUser';

@Injectable()
export class AuthService {
  private currentUserSubject: BehaviorSubject<User>;

  constructor() {
    this.currentUserSubject = new BehaviorSubject<User>(this.getUserFromLocalStorage())
    this.currentUserSubject.subscribe(user => this.setUserToLocalStorage(user));
  }

  logIn(userName: string, password: string) : Observable<User> {
    this.currentUserSubject.next({
      id: userName,
      userName: userName,
      email: userName
    });

    return this.currentUser.first();
  }

  logOut() {
    this.currentUserSubject.next(null);
  }

  get currentUser(): Observable<User> {
    return this.currentUserSubject.asObservable();
  }

  private getUserFromLocalStorage(): User {
    let userString = localStorage.getItem(LOCAL_STORAGE_KEY);

    if (!userString) {
      return null;
    }

    return JSON.parse(userString);
  }

  private setUserToLocalStorage(user: User) {
    if (user) {
      localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(user));
    }
    else {
      localStorage.removeItem(LOCAL_STORAGE_KEY);
    }
  }

}

これは機能しません:

export * from './auth.guard';
export * from './auth.service';

Unhandled Promise rejection: Error: Cannot resolve all parameters for 'AuthGuard'(undefined, Router). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'AuthGuard' is decorated with Injectable.

これは機能します:

export * from './auth.service';
export * from './auth.guard';

私が気づいたことから、これはすべてに当てはまるわけではありません。たとえば、認証サービスの後にユーザー モデルをエクスポートすると、正常に動作します。

毎回これを手動で変更する必要がなかったらいいのにと思います。利用可能な回避策はありますか? 別の方法でファイルを構成できますか?

からの依存関係package.json:

"@angular/common": "^2.0.0-rc.2",
"@angular/compiler": "^2.0.0-rc.2",
"@angular/core": "^2.0.0-rc.2",
"@angular/forms": "^0.1.0",
"@angular/http": "^2.0.0-rc.2",
"@angular/platform-browser": "^2.0.0-rc.2",
"@angular/platform-browser-dynamic": "^2.0.0-rc.2",
"@angular/router": "^3.0.0-alpha.7",
"bootstrap": "^3.3.6",
"es6-shim": "0.35.1",
"moment": "^2.13.0",
"ng2-bootstrap": "^1.0.17",
"reflect-metadata": "0.1.3",
"rxjs": "5.0.0-beta.6",
"slideout": "^0.1.12",
"systemjs": "0.19.26",
"zone.js": "0.6.12"

dev依存関係:

"angular-cli": "1.0.0-beta.6"
4

3 に答える 3

36

これは、バレル単位での輸出注文に関する問題です。ここのAngularレポで報告されています: https://github.com/angular/angular/issues/9334

次の 3 つの回避策があります。

バレル内のエクスポートの順序を変更します

モジュールの依存関係が依存関係の前にリストされるように順序を変更します。

この例では、AuthGuardは AuthServiceに依存しています。AuthService は AuthGuard の依存関係です。したがって、AuthGuard の前に AuthService をエクスポートします。

export * from './auth.service';
export * from './auth.guard';

バレルは一切使用しません。

これは、より多くのインポートが必要であることを意味するため、お勧めできません。

この例では、バレルではなくそのファイルから AuthService をインポートします。

import { AuthService } from './auth.service';
import { User } from './';

commonJS ではなく systemJS モジュール形式を使用する

typescript コンパイラ オプションを変更して、commonJS ではなく SystemJS 形式にコンパイルします。これは、tsconfig.jsoncompilerOptions.moduleを からcommonjsに変更することによって行われsystemます。

moduleIdその構成を変更するときは、すべてのコンポーネント デコレータのプロパティをからmodule.idに更新し、次のよう__moduleNameに宣言する必要があることに注意してください。typings.d.ts

declare var __moduleName: string;

このモジュール形式はAngular-CLIツール (Angular チームによって作成された公式のビルド ツール) のデフォルトではないため、推奨またはサポートされない場合があります。


注: 個人的には、どの回避策にも満足していません。

于 2016-06-19T13:22:16.373 に答える