Angular6 使用服务在组件之间共享数据
Angular 6 sharing data between components using Service
在我的主页组件中,它是 Dashboard 组件的子组件,在布局服务中注入的对象 connectedUser 在主页组件中未定义(主页组件日志中的主页用户 ID 和主页连接用户);
这里少了什么?
home.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HomeRoutingModule } from './home-routing.module';
import { HomeComponent } from './home.component';
/**
*
*
*
* @export
* @class AccueilModule
*/
@NgModule({
imports: [
CommonModule,
ReactiveFormsModule,
HomeRoutingModule,
FormsModule
],
declarations: [
HomeComponent
],
providers: [
]
})
export class HomeModule {}
dashboard.component.ts
import { Component, OnInit } from '@angular/core';
import { UserConnected } from 'src/app/models/userConnected';
import { LayoutService } from '../services/layout.service';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
currentDate: String;
userSaml = new UserConnected();
constructor(public layoutService: LayoutService) { }
ngOnInit(): void {
/* show today's date */
var today = new Date();
this.currentDate = today.getDate() + '/' + (today.getMonth() + 1) + '/' + today.getFullYear();
/* show today's date */
this.layoutService.getConnectedUser().subscribe(
(data) => {
this.userSaml = data;
this.layoutService.connectedUser.matricule = this.userSaml.matricule;
this.layoutService.connectedUser.profil = this.userSaml.profil;
this.layoutService.connectedUser.uid = this.userSaml.uid;
this.layoutService.connectedUser.username = this.userSaml.username;
this.layoutService.connectedUser.city = this.userSaml.city;
},
(err) => {
throw err;
}
);
}
}
应用-routine.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AppComponent } from './app.component';
import { DashboardComponent } from './shared/layout/dashboard/dashboard.component';
export const routes: Routes = [
{
path: '',
component: DashboardComponent
, children: [
{
path: '',
loadChildren: './home/home.module#HomeModule'
},
{
path: 'rapport',
loadChildren: '../rapport/rapport.module#RapportModule'
},
{
path: 'admin',
loadChildren: './admin/admin.module#AdminModule'
}
]
}];
@NgModule({
imports: [
RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
home.component.ts
import { Component, OnInit } from '@angular/core';
import { LayoutService } from '../shared/layout/services/layout.service';
import { UserConnected } from '../models/userConnected';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
constructor(public layoutService: LayoutService) { }
userID: string;
userExists : boolean = false;
connectedUser = new UserConnected;
ngOnInit() : void {
this.connectedUser = this.layoutService.connectedUser;
console.log("home connectedUser" + JSON.stringify(this.connectedUser));
this.userID = this.connectedUser.uid;
console.log("home userID" + this.userID);
this.adminService.verifyUser(this.userID)
.subscribe(
(data) => {
this.userExists = true;
},
(err) => {
this.userExists = false;
}
);
}
}
最后,这是我的布局服务
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '../../../../environments/environment';
import { UserConnected } from 'src/app/models/userConnected';
@Injectable({
providedIn: 'root'
})
export class LayoutService {
connectedUser : UserConnected;
constructor(private http:HttpClient) { }
getConnectedUser(){
return this.http.get<UserConnected>(environment.RAA_ROOT + '/connectedUser');
}
}
LayoutService
的 connectedUser 导致您的问题
connectedUser : UserConnected = new UserConnected();
这将为您提供 UserConnected class 的对象类型,因此您在访问时不会出现该错误它。快乐编码.. :)
首先,将 HomeComponent 中的行更改为:
this.connectedUser = this.layoutService.connectedUser;
进入:
this.connectedUser = this.layoutService.getConnectedUser()
由于您没有在 layoutService 中分配它,layoutService.connectedUser 将 return 未定义。
请注意,http.get 是异步的,因此它 return 是一个可观察对象,您需要订阅它才能在您的组件中使用它(或使用 asyncPipe如果您想在模板中使用它)。
更进一步:
this.layoutService.getConnectedUser().subscribe((connectedUser) => { this.connectedUser = connectedUser; })
更多解释在这里:
https://angular.io/tutorial/toh-pt6
我建议更改服务实现并引入更好的缓存:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '../../../../environments/environment';
import { UserConnected } from 'src/app/models/userConnected';
@Injectable({
providedIn: 'root'
})
export class LayoutService {
private _cachedConnectedUser: UserConnected;
constructor(private http:HttpClient) { }
getConnectedUser(): Observable<UserConnected> {
if (this._cachedConnectedUser ) {
return of(this._cachedConnectedUser);
}
return this.http.get<UserConnected>(environment.RAA_ROOT + '/connectedUser')
.map(response => {
this._cachedConnectedUser = response.body;
return this._cachedConnectedUser;
});
}
}
现在您可以随时调用 layoutService.getConnectedUser()
来接收对象。
您不必处理所有这些局部变量。
您甚至可以像解释的那样改进这种缓存机制here
在我的主页组件中,它是 Dashboard 组件的子组件,在布局服务中注入的对象 connectedUser 在主页组件中未定义(主页组件日志中的主页用户 ID 和主页连接用户); 这里少了什么?
home.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HomeRoutingModule } from './home-routing.module';
import { HomeComponent } from './home.component';
/**
*
*
*
* @export
* @class AccueilModule
*/
@NgModule({
imports: [
CommonModule,
ReactiveFormsModule,
HomeRoutingModule,
FormsModule
],
declarations: [
HomeComponent
],
providers: [
]
})
export class HomeModule {}
dashboard.component.ts
import { Component, OnInit } from '@angular/core';
import { UserConnected } from 'src/app/models/userConnected';
import { LayoutService } from '../services/layout.service';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
currentDate: String;
userSaml = new UserConnected();
constructor(public layoutService: LayoutService) { }
ngOnInit(): void {
/* show today's date */
var today = new Date();
this.currentDate = today.getDate() + '/' + (today.getMonth() + 1) + '/' + today.getFullYear();
/* show today's date */
this.layoutService.getConnectedUser().subscribe(
(data) => {
this.userSaml = data;
this.layoutService.connectedUser.matricule = this.userSaml.matricule;
this.layoutService.connectedUser.profil = this.userSaml.profil;
this.layoutService.connectedUser.uid = this.userSaml.uid;
this.layoutService.connectedUser.username = this.userSaml.username;
this.layoutService.connectedUser.city = this.userSaml.city;
},
(err) => {
throw err;
}
);
}
}
应用-routine.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AppComponent } from './app.component';
import { DashboardComponent } from './shared/layout/dashboard/dashboard.component';
export const routes: Routes = [
{
path: '',
component: DashboardComponent
, children: [
{
path: '',
loadChildren: './home/home.module#HomeModule'
},
{
path: 'rapport',
loadChildren: '../rapport/rapport.module#RapportModule'
},
{
path: 'admin',
loadChildren: './admin/admin.module#AdminModule'
}
]
}];
@NgModule({
imports: [
RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
home.component.ts
import { Component, OnInit } from '@angular/core';
import { LayoutService } from '../shared/layout/services/layout.service';
import { UserConnected } from '../models/userConnected';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
constructor(public layoutService: LayoutService) { }
userID: string;
userExists : boolean = false;
connectedUser = new UserConnected;
ngOnInit() : void {
this.connectedUser = this.layoutService.connectedUser;
console.log("home connectedUser" + JSON.stringify(this.connectedUser));
this.userID = this.connectedUser.uid;
console.log("home userID" + this.userID);
this.adminService.verifyUser(this.userID)
.subscribe(
(data) => {
this.userExists = true;
},
(err) => {
this.userExists = false;
}
);
}
}
最后,这是我的布局服务
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '../../../../environments/environment';
import { UserConnected } from 'src/app/models/userConnected';
@Injectable({
providedIn: 'root'
})
export class LayoutService {
connectedUser : UserConnected;
constructor(private http:HttpClient) { }
getConnectedUser(){
return this.http.get<UserConnected>(environment.RAA_ROOT + '/connectedUser');
}
}
LayoutService
的 connectedUser 导致您的问题
connectedUser : UserConnected = new UserConnected();
这将为您提供 UserConnected class 的对象类型,因此您在访问时不会出现该错误它。快乐编码.. :)
首先,将 HomeComponent 中的行更改为:
this.connectedUser = this.layoutService.connectedUser;
进入:
this.connectedUser = this.layoutService.getConnectedUser()
由于您没有在 layoutService 中分配它,layoutService.connectedUser 将 return 未定义。 请注意,http.get 是异步的,因此它 return 是一个可观察对象,您需要订阅它才能在您的组件中使用它(或使用 asyncPipe如果您想在模板中使用它)。
更进一步:
this.layoutService.getConnectedUser().subscribe((connectedUser) => { this.connectedUser = connectedUser; })
更多解释在这里: https://angular.io/tutorial/toh-pt6
我建议更改服务实现并引入更好的缓存:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '../../../../environments/environment';
import { UserConnected } from 'src/app/models/userConnected';
@Injectable({
providedIn: 'root'
})
export class LayoutService {
private _cachedConnectedUser: UserConnected;
constructor(private http:HttpClient) { }
getConnectedUser(): Observable<UserConnected> {
if (this._cachedConnectedUser ) {
return of(this._cachedConnectedUser);
}
return this.http.get<UserConnected>(environment.RAA_ROOT + '/connectedUser')
.map(response => {
this._cachedConnectedUser = response.body;
return this._cachedConnectedUser;
});
}
}
现在您可以随时调用 layoutService.getConnectedUser()
来接收对象。
您不必处理所有这些局部变量。
您甚至可以像解释的那样改进这种缓存机制here