使用Angular2和TypeScript将http功能移动到自己的服务中

时间:2016-02-05 14:24:31

标签: angularjs typescript angular rxjs

我在过去的4年里,在与Angular 1. *一起工作之后,正在尝试自学Angular2和TypeScript!无论如何,我有一个顶级组件,它创建一个属性,该属性派生自我在另一个类中创建的类型。在调用ngOnInit()时使用我的组件,我对作为后端编写的虚拟REST服务进行http调用。现在,当使用AngularJS编写应用程序时,我会将$http任务放入服务中并将它们注入我的控制器......我想对我的组件执行相同的操作。这是我的组件没有激活服务代码...注意评论

import {Component, OnInit} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {Home} from './components/home/home';
import {UserStatus} from './types/types.ts'; // this is why my UserStatus Type is kept
import {UserData} from './services/user-data/UserData.ts'; // here is where I wish to write my sevice to perform the http tasks...
import {Http, Headers} from 'angular2/http';

@Component({
    selector: 'app', // <app></app>
    providers: [...FORM_PROVIDERS],
    directives: [...ROUTER_DIRECTIVES],
    pipes: [],
    styles: [require('./app.scss')],
    template: require('./app.html')
})

export class App {

    userStatus: UserStatus;

    constructor(public http: Http) {
        this.userStatus = new UserStatus();
    }

    ngOnInit() {

        // I really want to put this code into a seperate class and provide it as a service...
        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        this.http.get('/restservice/userstatus', {headers: headers})
            .map((data: any) => data.json())
            .subscribe(
            (data: any) => {
                this.userStatus = data;
            },
            err => console.log(err), // error
            () => console.log('getUserStatus Complete') // complete

        );

        /* I'd like to factor the above into a service kept in a diffent file like so*/
        /*

         UserData.getUserStatus().then((resp) => {
            this.userStatus = resp;
         })
         */

    }
}

现在这里是我的类型......我的userStatus属性......

export class UserStatus {

    constructor (
        public firstName?: string,
        public fullPersId?: number,
        public goldUser?: boolean,
        public hasProfileImage?: boolean,
        public hideMoblieNavigationAndFooter?: boolean,
        public persId?: string,
        public profileName?: string,
        public profilePicture?: string,
        public showAds?: boolean,
        public siteId?:  number,
        public url?: string,
        public verified?: boolean,
        public appOS?: any,
        public formerName?: any
    ) {

        this.firstName = firstName || '';
        this.fullPersId = fullPersId || 0;
        this.goldUser = goldUser || false;
        this.hasProfileImage = hasProfileImage || false;
        this.hideMoblieNavigationAndFooter = hideMoblieNavigationAndFooter || false;
        this.persId = persId || '';
        this.profileName = profileName || '';
        this.profilePicture = profilePicture || '';
        this.showAds = showAds || false;
        this.siteId =  siteId || 0;
        this.url = url || '';
        this.verified = verified || false;
        this.appOS = appOS || null;
        this.formerName = formerName || null;

    }
}

现在我希望将我的Component的http功能放入一个serperate服务......我开始编写以下代码(请不要唠叨,我真的是Angular2的新手)

import {Injectable} from 'angular2/core';
import {Http, Headers} from 'angular2/http';
import {UserStatus} from '../../types/types.ts';

@Injectable()
export class UserData {

    constructor(public http:Http) {
    }

    getUserStatus(): any {
        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        this.http.get('/restservice/userstatus', {headers: headers})
            .map((data: any) => data.json())
            .subscribe(
            (data: any) => {
                return data;
            },
            err => console.log(err), // error
            () => console.log('getUserStatus Complete') // complete
        );
    }
}

现在我希望我可以调用服务getUserStatus()方法来执行HTTP数据获取并在我的App组件中调用它(我正在使用AngularJS 1.x承诺示例,但是我知道我应该真正使用可观察物......我只是不知道如何!)

ngOnInit() {

     UserData.getUserStatus().then((resp) => {
        this.userStatus = resp;
     });

    }

这显然是垃圾,我不知道我在做什么(Angular2的示例/教程似乎并不是那么好或实用到目前为止)。有人可以告诉我如何连接服务然后在我的组件中正确调用它吗?

2 个答案:

答案 0 :(得分:4)

我喜欢这个问题,因为我也走了同样的道路,不得不重构我的代码。 所以现在使用RxJs observables的最佳实践不是从http请求中返回.subscribe()方法中的json。只需映射并返回即可。 你正在做的是从它所有的额外信息中剥离它。

你应该返回observable,它是get()的整个实现。

getUserStatus(): any {
        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        return this.http.get('/restservice/userstatus', {headers: headers})
            .map((data: any) => data.json())
            .catch(this.handleError)
        );
    }

private handleError(error: Response) {
    // in a real world app, we may send the server to some remote logging infrastructure
    // instead of just logging it to the console
    console.error(error);
    return Observable.throw(error.json().error || 'Server error');
  }

然后在组件方面,您可以简单地订阅可观察的

export class App {
    public userStatus:any;
    // Have to inject the UserData Service it into our component here.
    constructor(public http: Http, private _userData: UserData ) {
    }

    ngOnInit() {
         this._userData.getUserStatus()
         .subscribe(
            (status) => {
              this.userStatus = status;
            },
            (err) => {
              console.log(err);
            },
            ()=>{console.log("User status complete")}
         );

        }
}

答案 1 :(得分:0)

这是angular2中最好的主题之一,所以我在这里回答这个问题;)

所以根据问题让我们来点

带有单独服务文件(代码)的Http请求

所以据我所知,这是最好的做法,为服务使用单独的文件(http请求)这样做我们通常在服务文件中执行http请求,然后在组件文件中订阅响应。我们还使用modal(typescript用于在问题中发布的类型检查)。您必须通过单独的服务文件更改您的代码,如下所示:

  

userStatus.ts:

import {Component, OnInit} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {Home} from './components/home/home';
import {UserStatus} from './types/types.ts'; // this is why my UserStatus Type is kept
import {UserData} from './services/user-data/UserData.ts'; // here is where I wish to write my sevice to perform the http tasks...
import {Http, Headers} from 'angular2/http';

@Component({
    selector: 'app', // <app></app>
    providers: [...FORM_PROVIDERS,UserStatus], //better to import FORM_PROVIDERS and basic providers at the time of bootstrapin
    directives: [...ROUTER_DIRECTIVES],
    pipes: [],
    styles: [require('./app.scss')],
    template: require('./app.html')
})

export class App implements OnInit {
    constructor(private userStatus:UserStatus){

    }

    ngOnInit(){
        this.serviceCalled();
    }

    serviceCalled(){
        userData.getUserStatus(url or path to json....)
            .subscribe(res=>{
                //get your data and CODE HERE....
                console.log(res)
            })
    }
}
  

,您的组件文件应如下所示:

Http request

为了参考目的,你也可以为cinterval = setInterval('time_dec()', 1000);

读出我的这些答案
  

https://stackoverflow.com/a/34823818/5043867

     

https://stackoverflow.com/a/34758630/5043867

希望它可以帮助您并明确与您的问题相关的一些观点!