[英]Angular: Access this.id declared in an “OnInit” function
After I read Alexanders suggestions, I updated the code and got no error back. 在阅读了Alexanders的建议之后,我更新了代码,没有错误返回。 But Angular doesn't do a request to the server anymore, which make me curious.
但是Angular不再向服务器发出请求,这使我感到好奇。 And also the
pageTitle
does not update. 而且
pageTitle
也不会更新。
{{appointmentDetail.time}}
import { Component, OnInit, OnDestroy, Injectable } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { Title } from '@angular/platform-browser';
import { APIService } from './../../../api.service';
import { Observable } from 'rxjs';
import { switchMap, tap } from 'rxjs/operators';
@Component({
selector: 'app-appointmentdetail',
templateUrl: './appointmentDetail.component.html',
styleUrls: ['./appointmentDetail.component.scss']
})
export class AppointmentDetailComponent implements OnInit {
id: any;
appointmentDetail$: Observable<Object>; // I'd really create an interface for appointment or whatever instead of object or any
pageTitle = 'Some Default Title Maybe';
constructor(
private route: ActivatedRoute,
private title: Title,
private apiService: APIService
) {}
ngOnInit() {
this.appointmentDetail$ = this.route.paramMap.pipe(
tap((params: ParamMap) => {
this.id = params.get('id');
// Or this.id = +params.get('id'); to coerce to number maybe
this.pageTitle = 'Termin' + this.id;
this.title.setTitle(this.pageTitle);
}),
switchMap(() => this.apiService.getAppointmentDetailsById(this.id))
);
}
public getData() {
this.apiService
.getAppointmentDetailsById(this.id)
.subscribe((data: Observable<Object>) => {
this.appointmentDetail$ = data;
console.log(data);
});
}
}
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class APIService {
API_URL = 'http://localhost:5000';
constructor(private httpClient: HttpClient) {}
getAppointments() {
return this.httpClient.get(`${this.API_URL}/appointments/`);
}
getAppointmentDetailsById(id) {
return this.httpClient.get(`${this.API_URL}/appointments/${id}`);
}
getAppointmentsByUser(email) {
return this.httpClient.get(`${this.API_URL}/user/${email}/appointments`);
}
getCertificatesByUser(email) {
return this.httpClient.get(`${this.API_URL}/user/${email}/certificates`);
}
}
As you can see, I want to grab that parameter id
from the router parameters and want to pass it into my API call, which will do a Angular HTTP request. 如您所见,我想从路由器参数中获取该参数
id
,并将其传递到我的API调用中,该API调用将执行Angular HTTP请求。 Hope I'm right, haha. 希望我是对的,哈哈。
Currently, I ran into a nasty problem. 目前,我遇到了一个令人讨厌的问题。 The thing is, I want to read the params, which are given to me by
ActivatedRouter
and the Angular OnInit
function. 问题是,我想阅读由
ActivatedRouter
和Angular OnInit
函数提供给我的参数。 I subscribe them params and log them in the console. 我订阅了它们的参数并将其记录在控制台中。 Until here, everything is working fine.
到这里为止,一切工作正常。 But I want to access "
this.id
" outside from my OnInit
function, so I can use it on pageTitle for example. 但是我想从
OnInit
函数外部访问“ this.id
”,因此我可以在例如pageTitle上使用它。
But, this.id is undefined. 但是,this.id是未定义的。 So the page title is Termineundefined.
因此页面标题是Termineundefined。
Source code: 源代码:
import { Component, OnInit, OnDestroy, Injectable } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Title } from '@angular/platform-browser';
import { APIService } from './../../api.service';
@Component({
selector: 'app-appointment-details',
templateUrl: './appointment-details.component.html',
styleUrls: ['./appointment-details.component.scss']
})
@Injectable()
export class AppointmentDetailsComponent implements OnInit, OnDestroy {
private routeSub: any;
id: any;
private appointmentDetail: Array<object> = [];
constructor(
private route: ActivatedRoute,
private title: Title,
private apiService: APIService
) {}
pageTitle = 'Termin' + this.id;
ngOnInit() {
this.title.setTitle(this.pageTitle);
this.getData();
this.routeSub = this.route.params.subscribe(params => {
console.log(params);
this.id = params['id'];
});
}
ngOnDestroy() {
this.routeSub.unsubscribe();
}
public getData() {
this.apiService
.getAppointmentDetailsById(this.id)
.subscribe((data: Array<object>) => {
this.appointmentDetail = data;
console.log(data);
});
}
}
The issue here really comes down to async availability of route params and observable streams. 这里的问题实际上归结为路由参数和可观察流的异步可用性。 You simply cannot use the value until it has resolved for all practical purposes.
您不能使用该值,直到将其解析为所有实际用途为止。 You can use RxJS operators such as
switchMap
and tap
in line with the official Routing & Navigation documentation to ensure route param id
is available prior to use. 您可以使用RxJS运营商如
switchMap
和tap
符合官方的路线选择和导航文件,以确保航线PARAM id
,请在使用前。 tap
can be used to introduce side effects such as setting class id
property from route params and/or setting title. tap
可以用于引入副作用,例如从路由参数设置类别id
属性和/或设置标题。 You could even create a class property of an Observable<YourObject[]>
and utilize Angular Async Pipe to avoid subscribing and unsubscribing to display the data. 您甚至可以创建
Observable<YourObject[]>
的类属性,并利用Angular Async Pipe避免订阅和取消订阅来显示数据。
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Title } from '@angular/platform-browser';
import { APIService, MyFancyInterface } from './../../api.service';
import { Observable } from 'rxjs';
import { switchMap, tap } from 'rxjs/operators';
@Component({
selector: 'app-appointment-details',
templateUrl: './appointment-details.component.html',
styleUrls: ['./appointment-details.component.scss']
})
export class AppointmentDetailsComponent implements OnInit {
id: any;
appointmentDetail$: Observable<MyFancyInterface>;
appointmentDetail: MyFancyInterface;
pageTitle = 'Some Default Title Maybe';
constructor(
private route: ActivatedRoute,
private title: Title,
private apiService: APIService
) {}
ngOnInit() {
this.appointmentDetail$ = this.route.paramMap.pipe(
tap((params: ParamMap) => {
this.id = params.get('id')
// Or this.id = +params.get('id'); to coerce to type number maybe
this.pageTitle = 'Termin' + this.id;
this.title.setTitle(this.pageTitle);
}),
switchMap(() => this.apiService.getAppointmentDetailsById(this.id))
);
/* Or
this.route.paramMap.pipe(
tap((params: ParamMap) => {
this.id = params.get('id')
// Or this.id = +params.get('id'); to coerce to type number maybe
this.pageTitle = 'Termin' + this.id;
this.title.setTitle(this.pageTitle);
}),
switchMap(() => this.apiService.getAppointmentDetailsById(this.id))
).subscribe((data: MyFancyInterface) => {
this.appointmentDetail = data;
});
*/
}
}
Template: 模板:
<div>{{(appointmentDetail | async)?.id}}</div>
I'd recommend to create an interface to represent your data model and type the return of your api service method: 我建议创建一个接口来表示您的数据模型,并键入api服务方法的返回值:
import { Observable } from 'rxjs';
// maybe put this into another file
export interface MyFancyInterface {
id: number;
someProperty: string;
...
}
export class APIService {
...
getAppointmentDetailsById(id): Observable<MyFancyInterface> {
return this.httpClient.get<MyFancyInterface>(`${this.API_URL}/appointments/${id}`);
}
...
}
If you really must, you can save the observable as you do now for the route params and subscribe as needed in the various parts of the class, but this demonstrated way you almost absolutely know that route param id
will be available for use and can explicitly set the things you need to set. 如果确实需要,您可以像现在所做的那样保存路由参数的可观察对象,并根据需要在课程的各个部分进行订阅,但是通过这种演示方式,您几乎可以完全知道路由参数
id
可以使用,并且可以显式地使用设置您需要设置的东西。
I'd also remove @Injectable()
as there is no reason to have it here with a @Component()
decorator. 我还将删除
@Injectable()
因为没有理由在这里使用@Component()
装饰器。
Note* the async pipe operator in this example ensures the Http call is executed. 注意*此示例中的异步管道运算符确保执行Http调用。 Otherwise a subscribe() is needed (search SO for Angular http not executing to see similar issues)
否则需要一个subscribe()(在SO中搜索Angular http无法执行以查看类似问题)
Hopefully that helps! 希望有帮助!
Instead of 代替
id: any;
You could try using a getter, like so 您可以像这样尝试使用吸气剂
public get id(): any {
this.route.params.subscribe(params => {
return params['id'];
}
}
In your template, just 在您的模板中,
{{ id }}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.