Angular2 service not being injected as singleton

丶灬走出姿态 提交于 2019-12-13 07:59:57

问题


I have the following service defined:

@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"; }

This is called from the login component:

@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;
 }

However, when there is a successful login, it redirects to the home route and the authentication guard starts up a new instance of the user service, which because it is a new instance returns undefined for the authenticated user

@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;
}
}

My module is declared like so:

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

My routing class is the following:

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 { }

The user service constructor code is firing both when the login page is hit, and when a successful authentication occurs.

My understanding is that this kind of problem happens when UserService is defined in both the component and the module, but in my case the module is the only place where this is defined.


回答1:


Not sure how it looks like right now, but in Angular2 rc.4 I could use this approach:

bootstrap.ts

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

let singletonServices = [
  singletonServiceNr1,
  singletonServiceNr2
];

bootstrap(AppComponent, [singletonServices]);

Than you inject singletonServiceNr1, or singletonServiceNr2 in desired component in normal way. They are singletons now.


In your case you should propably do the same thing:

@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 { }



回答2:


The solution was found in the following stackoverflow:

Angular2 router.navigate refresh page

This led me to test it in Internet Explorer, which worked OK (it was not working in Chrome)

It turned out that the entire page was refreshing when the following line was executed:

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

Which was causing the user service to reload again, because without a type on the button, Chrome's default action was to treat the button click as a submit.

The fix was to add the tag type="button" to the login button in the html

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

It now works in all browsers.



来源:https://stackoverflow.com/questions/42084732/angular2-service-not-being-injected-as-singleton

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!