在Angular5

时间:2018-01-24 16:21:08

标签: angular typescript angular-reactive-forms

我正在寻找使用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?

我很感激任何意见。

2 个答案:

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

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

希望这有帮助。