Angular2服务未被注入单身人士

时间:2017-02-07 08:11:06

标签: angular singleton

我定义了以下服务:

@Injectable()
export class UserService {

private _users: User[] = []
private _currentUser:User;

///Creates an instance of the Angular2 Http Service 
 constructor(private _http: Http) {console.log("in the constructor"; }

这是从登录组件调用的:

@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
 })
export class LoginComponent implements OnInit {
returnUrl: string;

constructor(private _userService: UserService,
          private route: ActivatedRoute,
          private router: Router)   { }

 validateUser(username: string, password: string): boolean {
  var loggedOnUser = this._userService.checkLogin(username, password);
  ...//check if logged on
 this.router.navigate([this.returnUrl]);

  return true;
 }

但是,当成功登录时,它会重定向到主路由,并且身份验证保护启动用户服务的新实例,因为它是新实例,对于经过身份验证的用户返回undefined

@Injectable()
export class AuthGuard implements CanActivate {

constructor(private router: Router, private _userService: UserService) { }

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {

    if (this._userService.getAuthenticatedUser()) //is undefined?????
    {
        return true;
    }

    // not logged in so redirect to login page with the return url
    this.router.navigate(['/login'], { queryParams: { returnUrl: state.url    }});
    return false;
}
}

我的模块声明如下:

@NgModule({
 declarations: [
AppComponent,
LoginComponent,
HomeComponent,
ManageUsersComponent,
StandingDataComponent
 ],
 imports: [
BrowserModule,
FormsModule,
HttpModule,
AppRoutingModule
 ],
providers: [AuthGuard,UserService],
bootstrap: [AppComponent]
})
export class AppModule { }

我的路由类如下:

const appRoutes: Routes = [
{path: '', component: HomeComponent, canActivate:[AuthGuard]},    
{ path: 'login', component: LoginComponent },
{path: 'home', 
component:HomeComponent, canActivate:[AuthGuard],
children: [{path: 'manageusers', component: ManageUsersComponent, outlet: 'innerPage'},
            {path: 'standingdata', component: StandingDataComponent, outlet: 'innerPage'}]
}, 
// otherwise redirect to home
{ path: '**', redirectTo: '' }];

@NgModule({
    imports: [RouterModule.forRoot(appRoutes)],

exports: [RouterModule]
})
export class AppRoutingModule { }

用户服务构造函数代码在命中登录页面和成功进行身份验证时都会触发。

我的理解是,当在组件和模块中定义UserService时会发生这种问题,但在我的情况下,模块是唯一定义它的地方。

2 个答案:

答案 0 :(得分:0)

不确定它现在的样子,但是在Angular2 rc.4中我可以使用这种方法:

bootstrap.ts

import {AppComponent} from './components/AppComponent;
import { singletonServiceNr1, singletonServiceNr2) from './services/Services;

let singletonServices = [
  singletonServiceNr1,
  singletonServiceNr2
];

bootstrap(AppComponent, [singletonServices]);

比以正常方式在所需组件中注入singletonServiceNr1singletonServiceNr2。他们现在是单身人士。

在你的情况下,你应该做同样的事情:

@NgModule({
 declarations: [
AppComponent,
LoginComponent,
HomeComponent,
ManageUsersComponent,
StandingDataComponent
 ],
 imports: [
BrowserModule,
FormsModule,
HttpModule,
AppRoutingModule
 ],
providers: [AuthGuard,UserService],
bootstrap: [AppComponent, UserService]     // note the change here
})
export class AppModule { }

答案 1 :(得分:0)

在以下stackoverflow中找到了解决方案:

Angular2 router.navigate refresh page

这导致我在Internet Explorer中测试它,它工作正常(它在Chrome中不起作用)

事实证明,执行以下行时整个页面都在刷新:

this.router.navigate([this.returnUrl]);

导致用户服务再次重新加载,因为按钮上没有类型,Chrome的默认操作是将按钮点击视为提交。

修复方法是将标签 type ="按钮" 添加到html中的登录按钮

<button type="button" class="btn btn-primary"(click)="validateUser(username, password)">Login</button>

它现在适用于所有浏览器。