我对角度/离子应用程序开发很陌生。我在某处阅读了以下内容
接口仅在编译时。这样只允许您检查收到的预期数据是否遵循特定结构。
我正在创建一个离子应用程序,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)如果我在一个提供商内部有多个接口,比如一个用于登录数据,另一个用于用户个人资料数据或其他什么,我应该在哪里放置它?我可以将它保存在单独的文件中并导出吗?我没有看到任何创建接口的离子命令
谢谢!我不想从错误开始我的职业生涯。这就是为什么我想发布这个。
答案 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的单独文件夹,并为每个界面创建新文件。