2017-05-04 49 views
0

我想知道推荐的方式来验证通过AJAX从服务器接收的数据或在Angular2 +应用程序中通过@input修饰器从子组件中接收的数据。在应用程序,我目前的工作与我使用的接口,这一点,但他们不验证输入的数据,即某些属性缺失时,发出有关无效型没有运行时错误:使用TypeScript和Angular2验证传入数据的类型

// types.ts 
export interface IAuthItem { 
name: string; 
type: number; 
description: string; 
rule_name: string | any; 
data?: any; 
created_at: number; 
updated_at: number; 
selected?: boolean; 
} 

export interface IAuthItemFormModel { 
AuthItem: IAuthItem; 
oldAuthItem: IAuthItem; 
permissions: IAuthItem[]; 
assignments: IAuthItem[]; 
} 

// component.ts 

//other imports 
import { IAuthItemFormModel, IAuthItem } from './types.ts'; 

.... 

@Input() model: IAuthItemFormModel; 

    ngOnInit() { 
    this.getData(); 
} 

getData() { 
    this.http.post('/api/admin/auth-item/form-data', 
    this.model).subscribe((data: IAuthItemFormModel) => { 
    this.model = Object.assign(this.model, data); 
    console.log(this.model); 
    }); 
} 
+1

接口不存在于运行时,所以你不能真正做任何通过他们解析的。我最近一直在使用的方法是直接使用类(接口是一个intead,你创建一个类并在其构造函数中传入http响应)。通过这种方式,你必须编写更多的代码,但是如果最终需要的话,你可以很容易地跟踪什么是不工作的。不确定它是否是最好的选择,但是自从我开始使用打字稿以来它一直在工作。 – briosheje

+0

谢谢,你能提供一个在http响应中使用类构造函数的例子吗? – Lyuba

+0

当然,我会在下面发表。 – briosheje

回答

0

免责声明:这是纯粹的一种可能的方法的例子,这并不意味着它需要有效或无论如何,这只是我最近使用的方法,并允许弹性,这正是我所寻找的。

现在,到了这一点。因为接口在运行时并不存在,所以如果你想解析并有效地添加任何种类的“测试”来获取所需的数据并最终转换所获取的数据,那么应该使用类。

这里是一个小例子,模拟这样的响应:

const json_response = { 
    status: "done", 
    refere: { 
     "id": 13, 
     "name": "John" 
    } 
}; 

在我们的情况下,我会申请是有一个响应处理器,是以整个反应的护理逻辑和Referee类也处理参考参考。

从裁判开始:

interface IReferee { 
    id: number, 
    name: string 
} 

class Referee implements IReferee { 
    public id: number; 
    public name: string; 

    private rawData: any; 

    constructor(data?: any) { 
     if (data !== null) { 
      // Do some check here to check whether data is effectively coherent. 
      this.id = +data.id; 
      this.name = data.name; 
     } 
    } 

    // This is the advantage of using a class. 
    // Adding optional methods that may be useful here and there. 
    get ID(): number { 
     return this.id; 
    } 

    get LowerCaseName(): string { 
     return this.name.toLowerCase(); 
    } 

    get Name(): string { 
     return this.name; 
    } 

    get UpperCaseName(): string { 
     return this.name.toUpperCase(); 
    } 
} 

的接口不是强制性的,它只是有用的,以确保您在类中正确地执行了一切。这里的优点是你可以实现你自己的方法(如上所示)。

响应处理程序:

interface IMyJsonResponseHandler { 
    status: string, 
    refere: Referee 
} 

class MyJsonResponseHandler implements IMyJsonResponseHandler { 
    private rawData: any; 

    public status: string; 
    public refere: Referee; 

    constructor(data?: any) { 
     if (data !== null) { 
      this.status = data.status; 
      this.refere = new Referee(data.refere); 
     } 
    } 

    get Refere(): Referee { 
     return this.refere; 
    } 
} 

而且相同的标准应用于:基本上,这里所提供的参数是JSON响应。每一次处理都是在构造函数中完成的,如果你想添加任何严格的检查,那么在那里执行并最终抛出错误或你需要的任何东西。通过这种方式,您可以访问几乎所有的json响应,并且可以通过接口和类一起享受intellisense。当然,你可以简单地接受JSON响应是无类型的,但是如果你需要做一些严格的检查并且需要这些数据用于其他计算,或者只是想更容易理解属性是什么,那么你必须使用类并做因为在这种情况下,打字稿中的界面不过是开发者的一种安慰。

实例:

const json_response = { 
    status: "done", 
    refere: { 
     "id": 13, 
     "name": "John" 
    } 
}; 
let res = new MyJsonResponseHandler(json_response); 

console.log(res.Refere.LowerCaseName); 

Playground with this example 哪些日志:john

该标准的优点:智能感知。您可以轻松实现一个接口,但是如果您需要复杂的数据阐述(或者更简单,如果您需要将内部属性作为类实例实例化),则必须使用其他条件。

其他来源,你应该检查:

How to parse JSON string in Typescript

How do I cast a JSON object to a typescript class

+0

谢谢你的详细回复) – Lyuba