我正在寻找使用Angular 5中的服务填充表单的最佳方法。我希望尽可能少的组件代码,这就是我的变量数据存储在服务中而不是组件中。
我的服务实际上是通过第二项服务加载内容。
示例服务:
@Injectable()
export class UserService {
private user: User;
private url: string = 'v1/user';
constructor(
private restService: RestService
) {
this.restService.get(this.url).subscribe(
res => {
this.user = res;
}
);
}
public getUser(): User {
return this.user;
}
示例组件:
export class UserComponent implements OnInit {
private form: FormGroup;
constructor(
private userService: UserService
) {}
ngOnInit(): void {
// Initalize the empty form
this.form = new FormGroup({
email: new FormControl()
})
);
// Fill the form with values from the service
this.form.patchValue(this.userService.getUser());
}
当我实际等待一段时间(比如使用setTimeout 10秒)然后执行patchValue()时一切正常,但显然这不是最佳的。
有没有办法知道服务中的代码何时被加载,除了去使用大锤破解坚果并使用Observable?
我很感激任何意见。
答案 0 :(得分:2)
您可以在组件内部订阅,也可以创建一个在完成后发出值的主题。
订阅组件内部
@Injectable()
export class UserService {
private user: User;
private url: string = 'v1/user';
constructor(private restService: RestService) {}
public getUser() {
return this.restService.get(this.url);
}
在component.ts
export class UserComponent implements OnInit {
private form: FormGroup;
userSub: Subscription;
user: string;
constructor(
private userService: UserService
) {}
ngOnInit(): void {
userSub = this.userService.getUser()
.subscribe( (res) => {
this.user = res;
// Initalize the empty form
this.form = new FormGroup({
'email': new FormControl(this.user, [])
})
);
});
}
订阅服务中的主题
@Injectable()
export class UserService {
userRetrieved: new Subject<User>();
private user: User;
private url: string = 'v1/user';
constructor(
private restService: RestService
) {
this.restService.get(this.url).subscribe(
(res) => {
this.user = res;
this.userRetrieved.next(this.user);
}
);
}
public getUser(): User {
return this.user;
}
然后在您的组件中订阅它
export class UserComponent implements OnInit {
userSub: Subscription;
private form: FormGroup;
constructor(
private userService: UserService
) {}
ngOnInit(): void {
// Initalize the empty form
this.form = new FormGroup({
email: new FormControl()
})
);
this.userSub = this.userService.userChanged
.subscribe((res: User ) => {
//Code to update and Fill the form with values from the service
// this.form.patchValue(res);
});
}
答案 1 :(得分:1)
是的,您实际上可以使您的服务充当解析器并以此方式实现您的目标。
@Injectable()
export class UserService implements Resolve<any> {
private user: User;
private url: string = 'v1/user';
constructor(
private restService: RestService
) {}
public resolve(route: ActivatedRouteSnapshot): Observable<any> {
return this.restService.get(this.url).map(
user => {
this.user = user;
},
error => {}
).first();
}
}
然后在您的路由器中,您将服务添加到您的路线中,就像您为正常的解析器所做的那样。
const routes: Routes = [
{
path: 'user',
component: UserComponent,
resolve: {
user: UserService
}
}
]
@NgModule({
imports: [ RouterModule.forRoot(routes)],
exports: [RouterModule],
providers: [UserService]
})
这样,每次您在应用中导航时都会刷新服务数据。
希望这有帮助。