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"

开发依赖:

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

3 回答 3

36

这是以桶为单位订购出口产品的问题。它已在此处的角度回购中报告:https ://github.com/angular/angular/issues/9334

有三种解决方法:

更改桶中出口的顺序

更改顺序,以便在其依赖项之前列出模块依赖项。

在此示例中,AuthGuard依赖于 AuthService。AuthService 是 AuthGuard 的一个依赖。因此,在 AuthGuard 之前导出 AuthService。

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

根本不要使用桶。

不建议这样做,因为这意味着需要更多的导入。

在此示例中,您将从其文件而不是桶中导入 AuthService。

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

使用 systemJS 模块格式而不是 commonJS

更改 typescript 编译器选项以编译为 SystemJS 格式而不是 commonJS。这是通过将 tsconfig.jsoncompilerOptions.module从更改为commonjs来完成的system

请注意,当您更改该配置时,您需要将moduleId所有组件装饰器的属性从module.idto更新__moduleName并声明typings.d.ts如下:

declare var __moduleName: string;

此模块格式不是Angular-CLI工具(由 Angular 团队创建的官方构建工具)中的默认格式,因此可能不推荐或不支持。


注意:我个人对任何解决方法都不满意。

于 2016-06-19T13:22:16.373 回答
5

我遇到了这个问题,这是由循环引用引起的。说明:在“提供者服务类”中,我有一个 UI 页面的引用,构造函数引用了这个相同的服务,导致循环引用......

import { MyUIPage } from "../pages/example/myuipage";

所以我必须做的是从服务中删除引用并构建一个接收回调的函数。无需从服务中引用 UI 页面,错误就会消失。

public setCallBackSpy(callback)
{
   this.callBackSpy = callback;
}

在引用服务的 app.component 类构造函数中,我只需将链接设置为回调函数,如下所示。

this.servicingClass.setCallBackSpy(this.myCallBackFunctionUsingUIPage);

希望有帮助,我的第一个答案:)

于 2017-07-06T17:54:20.847 回答
1

您也可以在 Angular2 live 中遇到此错误,并建议 Angular 不想实例化已经实例化的服务。如果您在 @Component 类装饰器的 providers 属性中“错误”包含了服务,例如来自 '@angular/router' 的 ActivatedRoute,尽管已经将 RouterModule 包含在 App.module 文件中,无论如何注册所有路由器提供程序,它都可能发生和应用程序的指令。

于 2016-09-23T03:26:58.747 回答