我正在寻找用 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 之外,有没有办法知道服务中的代码何时加载?
我感谢任何投入。
您可以在组件中订阅,也可以创建一个主题,该主题在完成后发出值。
在组件内部订阅
@Injectable()
export class UserService {
private user: User;
private url: string = 'v1/user';
constructor(private restService: RestService) {}
public getUser() {
return this.restService.get(this.url);
}
在组件中
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);
});
}
是的,您实际上可以使您的服务充当解析程序并以这种方式实现您的目标。
@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]
})
这样,每次在应用中导航时都会刷新服务数据。
希望这有帮助。