Angular 5 - 组件和服务之间的通信
Angular 5 - communication between Components and Services
我用Angular 5.
目的是在登录正常时加载数据,并在其他组件中使用这些数据。
使用 Services Class 和 getActiveTasks 方法和 getStats 方法加载数据。
登录组件:
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent {
constructor(private auth: AuthenticationService,
private klinckServices: KlinckServices,
private router: Router) { }
loadData($event) {
console.log('Authentification OK');
let success;
this.klinckServices.getActiveTasks(this.auth.getEcmUsername())
.then((webScriptdata) => {
console.log('KlinckSercices - loadData');
success = webScriptdata;
this.klinckServices.listTasks = success.data as ActiveTask[];
this.router.navigate([this.klinckServices.getStats()]);
console.log(this.klinckServices.listServices);
},
msg => {
alert(msg);
return '';
});
// this.router.navigate([this.klinckServices.loadData()]);
}
}
服务Class:
@Injectable()
export class KlinckServices {
listTasks: ActiveTask[];
listServices: Stats [] = [];
constructor(private apiService: AlfrescoApiService,
private auth: AuthenticationService) {
console.log('KlinckServices - constructor');
}
getStats(): string {
this.listTasks.forEach((item, index) => {
if (this.getServicesInListTasks(item.properties.wfvd_nomService) !== null) {
if (! this.getServicesInListServices(item.properties.wfvd_nomService)) {
const listLength = this.listTasks.filter(item2 => item2.properties.wfvd_nomService === item.properties.wfvd_nomService).length;
console.log(listLength);
const at: ActiveTask[] = [];
for (let i = 0; i < listLength; i++) {
at.push(this.listTasks.filter(item2 => item2.properties.wfvd_nomService === item.properties.wfvd_nomService)[i]);
}
this.listServices.push({
data: at,
count: listLength,
service: item.properties.wfvd_nomService
});
}
}
});
return '/dashboard';
}
getServicesInListServices( serviceSearch: string) {
return(this.listServices.find( x => x.service === serviceSearch));
}
getServicesInListTasks( serviceSearch: string) {
return(this.listTasks.find( x => x.properties.wfvd_nomService === serviceSearch));
}
加载仪表板组件后,我需要检索这些数据:
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit, AfterViewInit
{
@ViewChild(DataTableDirective) datatableElement: DataTableDirective;
@Input() public klinckServices: KlinckServices;
listTasks: ActiveTask[];
listPatients: Patient[];
listMedecins: Medecin[];
listDocType: Typologie[];
listServices: Stats [] = [];
dtOptions: any = {};
docNodeId: string;
detailTaskId: any;
constructor(private auth: AuthenticationService,
public dialog: MatDialog,
private http: HttpClient)
{
console.log('DashboardComponent - constructor');
this.listServices = this.klinckServices.listServices;
console.log(this.listServices);
this.getPatients();
this.getMedecins();
this.getDocumentType();
}
但我在控制台中收到此错误消息:"ERROR TypeError: Cannot read property 'listServices' of undefined"
那么在组件和服务之间进行通信的最佳方式是什么?
例如您可以:
- 在Angular中使用单例服务,登录时加载一次数据
- 不在登录时加载数据,而是在仪表板初始化时加载数据(接口 U 在 class 定义中使用的 OnInit 方法 - 当然,您必须在构造函数中注入 KlinkService 才能将其用作 @CornelC 在他的回答中提到)。
你的其他问题:为什么你不在 KlinkService.getActiveTasks
的服务中使用 Rxjs(它是 angualar 的标准)(因为你称它为 promise)?
您应该像在 LoginComponent
中那样注入服务
constructor(private klinckServices: KlinckServices
你也应该提供给模块
providers: [KlinckServices]
我用Angular 5. 目的是在登录正常时加载数据,并在其他组件中使用这些数据。 使用 Services Class 和 getActiveTasks 方法和 getStats 方法加载数据。 登录组件:
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent {
constructor(private auth: AuthenticationService,
private klinckServices: KlinckServices,
private router: Router) { }
loadData($event) {
console.log('Authentification OK');
let success;
this.klinckServices.getActiveTasks(this.auth.getEcmUsername())
.then((webScriptdata) => {
console.log('KlinckSercices - loadData');
success = webScriptdata;
this.klinckServices.listTasks = success.data as ActiveTask[];
this.router.navigate([this.klinckServices.getStats()]);
console.log(this.klinckServices.listServices);
},
msg => {
alert(msg);
return '';
});
// this.router.navigate([this.klinckServices.loadData()]);
}
}
服务Class:
@Injectable()
export class KlinckServices {
listTasks: ActiveTask[];
listServices: Stats [] = [];
constructor(private apiService: AlfrescoApiService,
private auth: AuthenticationService) {
console.log('KlinckServices - constructor');
}
getStats(): string {
this.listTasks.forEach((item, index) => {
if (this.getServicesInListTasks(item.properties.wfvd_nomService) !== null) {
if (! this.getServicesInListServices(item.properties.wfvd_nomService)) {
const listLength = this.listTasks.filter(item2 => item2.properties.wfvd_nomService === item.properties.wfvd_nomService).length;
console.log(listLength);
const at: ActiveTask[] = [];
for (let i = 0; i < listLength; i++) {
at.push(this.listTasks.filter(item2 => item2.properties.wfvd_nomService === item.properties.wfvd_nomService)[i]);
}
this.listServices.push({
data: at,
count: listLength,
service: item.properties.wfvd_nomService
});
}
}
});
return '/dashboard';
}
getServicesInListServices( serviceSearch: string) {
return(this.listServices.find( x => x.service === serviceSearch));
}
getServicesInListTasks( serviceSearch: string) {
return(this.listTasks.find( x => x.properties.wfvd_nomService === serviceSearch));
}
加载仪表板组件后,我需要检索这些数据:
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit, AfterViewInit
{
@ViewChild(DataTableDirective) datatableElement: DataTableDirective;
@Input() public klinckServices: KlinckServices;
listTasks: ActiveTask[];
listPatients: Patient[];
listMedecins: Medecin[];
listDocType: Typologie[];
listServices: Stats [] = [];
dtOptions: any = {};
docNodeId: string;
detailTaskId: any;
constructor(private auth: AuthenticationService,
public dialog: MatDialog,
private http: HttpClient)
{
console.log('DashboardComponent - constructor');
this.listServices = this.klinckServices.listServices;
console.log(this.listServices);
this.getPatients();
this.getMedecins();
this.getDocumentType();
}
但我在控制台中收到此错误消息:"ERROR TypeError: Cannot read property 'listServices' of undefined"
那么在组件和服务之间进行通信的最佳方式是什么?
例如您可以:
- 在Angular中使用单例服务,登录时加载一次数据
- 不在登录时加载数据,而是在仪表板初始化时加载数据(接口 U 在 class 定义中使用的 OnInit 方法 - 当然,您必须在构造函数中注入 KlinkService 才能将其用作 @CornelC 在他的回答中提到)。
你的其他问题:为什么你不在 KlinkService.getActiveTasks
的服务中使用 Rxjs(它是 angualar 的标准)(因为你称它为 promise)?
您应该像在 LoginComponent
constructor(private klinckServices: KlinckServices
你也应该提供给模块
providers: [KlinckServices]