ionic / angular-如何正确使用接口?

时间:2018-02-22 05:20:07

标签: angular typescript ionic-framework ionic2

我对角度/离子应用程序开发很陌生。我在某处阅读了以下内容

接口仅在编译时。这样只允许您检查收到的预期数据是否遵循特定结构。

我正在创建一个离子应用程序,API服务会将一些数据返回给用户。让我们说它是一个登录功能,API服务会返回该数据。

我在Ionic中创建了一个提供程序,使用HTTPClient对API进行HTTP调用。

//Provider

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';

interface LoginResponse {
  success: boolean;
  message: string;
  token: string;
  userId: number;
}
@Injectable()
export class LoginServicesProvider {
  constructor(public http: HttpClient) {
  }

  login(reqData): Observable<LoginResponse[]> {
    return this.http.post<LoginResponse[]>('localhost:3000/api/login', reqData);
  }
}

如您所见,我创建了一个名为LoginResponse的接口

Login组件的代码如下:

//Component

import { LoginServicesProvider } from './../../providers/login-services/login-services';
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'page-login-page',
  templateUrl: 'login-page.html',
})
export class LoginPage {
  constructor(private loginService: LoginServicesProvider) {
  }

  onSubmit() {
    let reqParams = {
    email: 'afakeemail@id.com',
    password: 'password',
    };

    this.loginService.login(reqParams).subscribe(res => {
        console.log('success');
    });
  }
}

对于此示例,我只是将消息打印到控制台。

现在我的问题

1)如前面的声明中提到的那样,我的LoginResponse接口是否检查收到的数据?如果没有,我应该如何/在哪里实施该签到提供商或组件?

2)如果我在一个提供商内部有多个接口,比如一个用于登录数据,另一个用于用户个人资料数据或其他什么,我应该在哪里放置它?我可以将它保存在单独的文件中并导出吗?我没有看到任何创建接口的离子命令

谢谢!我不想从错误开始我的职业生涯。这就是为什么我想发布这个。

2 个答案:

答案 0 :(得分:7)

Typescript中的接口仅提供对象形状的描述。如果在TypeScript中创建对象,则编译器可以判断该对象是否与接口兼容。在运行时,接口被擦除,因此不会检查对象是否与接口兼容。当您使用post<T>发出请求时,您基本上是告诉编译器您希望作为响应的对象的形状T但是不会执行检查以确保这一点。

您可以在文件中拥有任意数量的接口,并且可以从该文件中导出它们,将它们导入到另一个文件中,就像您在类或函数中一样。您如何组织代码取决于您。

如果您想确保在运行时正确实现对象,请参阅here

答案 1 :(得分:4)

正如您所提到的,typescript中的接口仅用于定义合同。因此,在您的示例中,您只希望服务器的日志响应具有您在界面中提到的属性。在接口中没有约束我们应该提到在JSON响应中返回的所有属性。如果需要,您甚至可以在界面中添加更多属性,这些属性在JSON响应中不存在。 因此,在您的具体示例中,通过使用接口,您可以在将来检查代码时了解API的规范。所以下面将是我的实现

我将创建一个名为ILoginRequest.ts的新文件并声明名为ILoginRequest的接口

export interface ILoginRequest {
 email:string;
 password:string;
}

并将该接口用作提供程序类

中requestData输入参数的类型
login(reqData:ILoginRequest ): Observable<LoginResponse[]> {
return this.http.post<LoginResponse[]>('localhost:3000/api/login', reqData);

}

因此,如果我们在项目中的任何其他位置使用提供程序类中的login函数,我们就知道应该为login函数提供什么样的输入以及该函数的预期结果是什么。

在调用页面中将分配来自loginResponse变量的api的输出,该变量是接口LoginResponse类型。所以无论我们在类中使用这个变量,我们都知道我们可以使用的属性是什么,我们在IDE中获得了智能支持

export class LoginPage {
 private loginResponse : LoginResponse;
 constructor(private loginService: LoginServicesProvider) {
 }

onSubmit() {
let reqParams = {
email: 'afakeemail@id.com',
password: 'password',
};

this.loginService.login(reqParams).subscribe((res:LoginResponse) => {
    console.log('success');
    this.loginResponse = res;
});

} }

有关打字稿中界面用法的更多详细信息,您可以查看link

关于保留界面的位置,根据我的说法,只有开发人员偏好,您可以在“app”目录中创建名为interfaces的单独文件夹,并为每个界面创建新文件。