代码之家  ›  专栏  ›  技术社区  ›  Thayend

以Angular5从服务获取数据到反应式表单的最佳方法

  •  3
  • Thayend  · 技术社区  · 7 年前

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

    当我实际等待一段时间(比如10秒的setTimeout)然后执行patchValue()时,一切都正常,但显然这不是最佳的。

    除了去 用大锤敲螺母 使用可观察的?

    我很感谢大家的意见。

    2 回复  |  直到 7 年前
        1
  •  3
  •   Iancovici    7 年前

    您可以在组件内部进行订阅,也可以创建一个主题,在完成后发出值。

    订阅内部组件

    @Injectable()
    export class UserService {
    
    private user: User;
    
    private url: string = 'v1/user';
    
    constructor(private restService: RestService) {}
    
    
    
    public getUser() {
        return this.restService.get(this.url);
    }
    

    在组件中。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);
           });
    
    }
    
        2
  •  2
  •   PaNic175    7 年前

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

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

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

    希望这有帮助。