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

在组件中

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

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

希望这有帮助。

最新更新