Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
HTTP:从JSON对象到Typescript的类型断言_Json_Http_Typescript_Angular - Fatal编程技术网

HTTP:从JSON对象到Typescript的类型断言

HTTP:从JSON对象到Typescript的类型断言,json,http,typescript,angular,Json,Http,Typescript,Angular,我已经阅读了有关接口和类型断言的内容。我一直在看这样的网页: (这个和TS无关!) 我已经掌握了窍门,理解基本知识非常简单。但是:当涉及HTTP时,我找不到如何将JSON对象键入我在应用程序中使用的对象 例如,我有一个教师对象数组。每个教师都有一个id、姓名和一组学生。我有另一个班的学生,包含他们的属性。。。。。等等 在这些链接的某个地方,我读到,除非你需要对一个对象执行操作,只要有一个接口就足够了。但是,除非您想对对象执行操作,否则您需要一个单独的类 我的实际教师课程开始于…: ex

我已经阅读了有关接口和类型断言的内容。我一直在看这样的网页:

  • (这个和TS无关!)
我已经掌握了窍门,理解基本知识非常简单。但是:当涉及HTTP时,我找不到如何将JSON对象键入我在应用程序中使用的对象

例如,我有一个教师对象数组。每个教师都有一个id、姓名和一组学生。我有另一个班的学生,包含他们的属性。。。。。等等

在这些链接的某个地方,我读到,除非你需要对一个对象执行操作,只要有一个接口就足够了。但是,除非您想对对象执行操作,否则您需要一个单独的类

我的实际教师课程开始于…:

export class Teacher {

    private students: Array<Student>;

    constructor(public id: string, public name: string) {
        this.students = new Array<Student>();
    }

    public getStudents(): Array<Student> {
        return this.students;
    }

}
组件(角度2组件):

我的界面看起来像:

export interface TeacherJSON {
        id: string,
        name: string,
        students: Array<Student>;
}
我确实理解上面的例子,但我想http、映射和订阅让我很反感,我不知道如何在我的代码中实现它

显然,我需要首先将组件中的teachers数组更改为接口的实例

接口的实例是不存在的。接口是抽象的,它们只存在于TypeScript中,甚至不编译为JavaScript。您编写它们是为了在编辑器中获得代码完成和其他好处;在大型应用程序中为您提供帮助,这样您就不必记住每个对象都有哪些属性和方法

当您必须实例化一个对象时,接口不能这样做-您将使用一个类,并像往常一样创建属性和方法。在您的示例中,正确的方法是:

interface ITeacher{
  id: string,
  name: string,
  students: Array<Student>;
};
class Teacher implements ITeacher {
  id: string,
  name: string,
  students: Array<Student>;
}
如果您有几种类型的教师,并且您希望确保每种教师都具有所有必要的属性/方法,那么创建一个接口是有意义的:

class FirstGradeTeacher implements ITeacher{}
class SecondGradeTeacher implements ITeacher{}
你可能已经注意到我根本没有提到JSON<算了吧…使用对象模型(类或接口)时。它只是逻辑模型的数据格式。当您构建模型并规划它们应该如何工作时,您并不关心协议和格式(Http服务处理这些)


希望这有帮助(:

假设您通过http获取教师列表,您可以对其进行筛选以获取所需的教师列表:

getById(id: string) {
    return this.http.get('someUrl' + id)
        .map((res: Response) => res.json())
        .filter(teacher => teacher.id === id));

如果我很了解您的问题,您需要为反序列化JSON对象提供一些方法,该对象的原型为
对象
。目前,普通javascript API无法实现这一点,因为您从REST服务接收的内容是一个普通字符串,它通过
JSON.parse
成为对象。您应该使用另一种反序列化机制,能够在运行时检查类,并从反序列化的JSON重新构建它们的实例。通过这种方式,您将拥有新的JSON对象,但拥有正确的原型,该原型包含该类的所有方法。我将试着做一个示例

假设您正在调用一个REST端点,该端点为您提供类似
Teacher
的对象。在某些情况下,您可以执行
var freshObject=JSON.parse(receivedString)
(实际上,Angular已经完成了,但我们将改进此机制);最简单的操作(但不是最明智的操作)是将
freshObject
的原型更改为
Teacher
原型:
Object.setPrototypeof(freshObject,Teacher.prototype)
。现在您可以在
freshObject
上调用
Teacher
方法,但这显然是一个肤浅的更改,因为嵌套对象(
Student
s在本例中)仍然有
对象
作为其原型,问题再次出现

现在很明显,我们需要能够递归地调查
教师
类结构,同时使用正确的原型重新构建接收到的对象(实际上,您可以创建新的副本,而不是更改原型,这应该不会太重)。您可能需要类似于:
Teacher.getClass()。成员将为您提供以下信息:

  • 学生姓名
    字段
  • students
    字段的类型(
    Array
  • 组件类的构造函数
    Student
如果您有此类信息,您可以递归地执行与前面示例中相同的操作


我最近发布了一个增强版的TypeScript编译器,允许使用此用例。我为您准备了一个完整的工作示例,您可以找到编译器项目。请告诉我这是否解决了您的问题。

谢谢您的回答。当然,很难看到我的问题,因为您看不到完整的代码。我无法扩展我的Teac因为学生在课堂上是私人的,所以她的课和我的接口在一起。我让人看了我的代码,我被告知要实现一个接口来解决我的问题。我正在丢失数据,例如当我检索一名教师时。在那里,我必须将新来的教师映射为“新教师”老师,否则我会得到一个self.context错误。如果你看我的教师类,我只能说
new teacher(teacher.id,teacher.name)
。所以我已经在那里丢失了数据。在我的服务中添加了
getTeacher
方法来展示我丢失数据的一个问题。@Sasxa res.json()为什么转换为教师?我正在寻找一些说明这一点的文档。它没有转换,它仍然只是一个JSON。但是,因为您希望响应的结构与教师相同,所以您可以将其键入,并且您的工具和编辑器可以帮助您进行类型检查、自动完成、调试等@TomDeseyn@Sasxa我找不到强制转换操作。调用map返回Observable,它在哪里强制转换为Observable?再次感谢,但这对我没有帮助。顺便说一下,我已经尝试过这个解决方案。我到处都在丢失数据,所以我真的需要告诉我的代码
interface ITeacher{
  id: string,
  name: string,
  students: Array<Student>;
};
class Teacher implements ITeacher {
  id: string,
  name: string,
  students: Array<Student>;
}
teachers: Teacher[];
teachers: ITeacher[];
class FirstGradeTeacher implements ITeacher{}
class SecondGradeTeacher implements ITeacher{}
getTeachers(): Observable<Teacher> {
  return this.http.get('someUrl')
    .map((res: Response) => res.json())
}
this._service.getTeachers()
  .subscribe((teachers: Teacher[]) => this.teachers = teachers);
getById(id: string) {
    return this.http.get('someUrl' + id)
        .map((res: Response) => res.json())
        .filter(teacher => teacher.id === id));