在 Angular5 中从服务获取数据到反应形式的最佳方式

Best way to get data from a service to a reactive form in Angular5

我正在寻找用 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);
}

在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);
       });

}

是的,您实际上可以让您的服务充当解析器并以这种方式实现您的目标。

@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] 
})

这样,每次您在应用中导航时,服务数据都会刷新。

希望对您有所帮助。