M. *_* Ko 6 typescript angular
我是这种类型脚本的新手.这是我的模型类:
export class Project {
constructor(
public projectId: number,
public description: string,
public startDate: Date,
public endDate: Date
) {}
getDaysRemaining() {
var result = this.endDate.valueOf() - Date.now().valueOf();
result = Math.ceil(result / (1000 * 3600 * 24));
return result < 0 ? 0 : result;
}
}
Run Code Online (Sandbox Code Playgroud)
而且,下面是我的初始化,参考Angular教程:
let PROJECTS: Project[] = [
{ projectId: 1, description: "Sample", startDate: new Date("2016-12-12"), endDate: new Date("2017-1-13") },
{ projectId: 2, description: "Sample 2", startDate: new Date("2016-12-12"), endDate: new Date("2017-1-13") }
];
Run Code Online (Sandbox Code Playgroud)
该模型应该在模板中使用如下:
{{ project.getDaysRemaining() }}
Run Code Online (Sandbox Code Playgroud)
但是,我收到错误:
类型'{projectId:number;}中缺少属性'getDaysRemaining'; 描述:字符串; startDate:日期; endDate:日期; }".
为什么我必须在TypeScript中初始化函数?或者,我错过了什么?
and*_*eim 14
您的问题与实例化类的方式有关.
代替:
let PROJECTS: Project[] = [
{ projectId: 1, description: "Sample", startDate: new Date("2016-12-12"), endDate: new Date("2017-1-13") },
{ projectId: 2, description: "Sample 2", startDate: new Date("2016-12-12"), endDate: new Date("2017-1-13") }
];
Run Code Online (Sandbox Code Playgroud)
你应该做:
let PROJECTS: Project[] = [
new Project(1, "Sample", new Date("2016-12-12"), new Date("2017-1-13") ),
new Project(2, "Sample 2", new Date("2016-12-12"), new Date("2017-1-13")
];
Run Code Online (Sandbox Code Playgroud)
说明
Project
是一个班级.getDaysRemaining()
是该类的成员.要创建可以使用的类的实例new Project(...)
.
{ projectId: 1, ... }
是一个不是类实例的对象Project
.因此,所有成员都在括号之间定义为属性.
你可以通过简单的结果检查是否{ projectId: 1, ... }
是一个实例.Project
{
project1: 1, ... } instanceof Project
false
ES6?TypeScript与JavaScript语言的最新进展有很多共同的语法.您可以在ES6中定义类,就像在TypeScript中一样.当然,除了类型和修饰符之外,JavaScript不是静态类型语言,而是动态类型语言.
class Project {
constructor(projectId, description, startDate, endDate) {
this.projectId = projectId;
this.description = description;
this.startDate = startDate;
this.endDate = endDate;
}
getDaysRemaining() {
var result = this.endDate.valueOf() - Date.now().valueOf();
result = Math.ceil(result / (1000 * 3600 * 24));
return result < 0 ? 0 : result;
}
}
Run Code Online (Sandbox Code Playgroud)
在ES6中你可以做到new Project()
,undefined
为所有参数提供,但在TypeScript中不能,因为缺少构造函数参数,并且在编译时检查这个事实,并且如果有一个好的IDE检查TypeScript语法,那么也在设计时.
在TypeScript中允许此操作的一个选项是定义可选参数,如下所示(请参阅参数附近的问号):
constructor(
public projectId?: number,
public description?: string,
public startDate?: Date,
public endDate?: Date
) { }
Run Code Online (Sandbox Code Playgroud)
常见问题 - 从源(如Web服务)获取一些数据
Project
从Web服务获取数据时可能会遇到这种情况.在这种情况下,数据将被反序列化为普通对象{ projectId: 1, ... }
.Project
从该数据中获取实例无法隐式完成,还需要完成其他工作.
最简单的方法是在工厂方法中将每个属性从一侧传递到另一侧:
class Project implements IProject {
...
static create(data: IProject) {
return new Project(data.projectId, data.description, data.startDate, data.endDate);
}
...
}
Run Code Online (Sandbox Code Playgroud)
并且您可以使用接口(而不是any
)为您的数据在键入时提供额外的帮助,并实现它(class Project implements IProject
):
interface IProject {
projectId: number;
description: string;
startDate: Date;
endDate: Date;
}
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用可选参数,但这可能不适用于所有情况:
class Project implements IProject {
...
constructor(
public projectId?: number,
public description?: string,
public startDate?: Date,
public endDate?: Date
) { }
static create(data: IProject) {
return Object.assign(new Project(), data);
}
...
}
Run Code Online (Sandbox Code Playgroud)
因此,如果要像上面那样实现,接口将具有可选参数(检查问号):
interface IProject {
projectId?: number;
description?: string;
startDate?: Date;
endDate?: Date;
}
Run Code Online (Sandbox Code Playgroud)
将TypeScript转换为JavaScript时的编译和接口将从最终代码中删除所有接口.JavaScript中没有"接口"概念.这是TypeScript的构造,其目的是提供其他类型信息.
试着坚持 - S =单一责任原则
在上面的代码中Project
有两个职责(不是一个).第一是保留一些Project
数据.第二是计算剩余天数 - getDaysRemaining
.对于单个班级来说,这可能太多了.
一个干净的解决方案可能是将其分成两部分.
有一个界面来表示以下数据Project
:
interface IProject {
projectId: number;
description: string;
startDate: Date;
endDate: Date;
}
Run Code Online (Sandbox Code Playgroud)
并移动getDaysRemaining()
到另一个类,如:
class ProjectSchedulingService {
getDaysRemaining(project: IProject) {
var result = project.endDate.valueOf() - Date.now().valueOf();
result = Math.ceil(result / (1000 * 3600 * 24));
return result < 0 ? 0 : result;
}
}
Run Code Online (Sandbox Code Playgroud)
这样做的好处是,数据 - IProject
是独立的,其他功能可以放在其他自己的工作中 - 比如 - ProjectSchedulingService
.
另一个优点是IProject
可以帮助处理普通对象而不是实例化其他类.您可以从Web服务获取数据,将其转换为接口并以键入的方式工作.
另一个优点是业务可以分成多个类 - 例如ProjectSchedulingService
- 因此可以单独进行单元测试,而不是拥有数据及其中所有相关业务的繁重单片类.
另一个优点是拥有多个类有助于更容易地定义类之间的依赖关系,从而保持业务语义,并能够模拟类和单元的所有依赖关系来测试手头类的业务.
以Angular为例,您可以根据需要注入多个服务(类).拥有一个单一的服务意味着传递只需要其中一部分的东西.从而打破了界面隔离.
这可能听起来很愚蠢,因为代码很小,但随着时间的推移,这将继续增长,而下一代开发人员可能仍然以相同的单片方式继续开发而不是重构.经过一段时间后,由于维护代码的难度,许多估计值会增加或被破坏.也圈复杂度变得最坏,也为单元测试代码覆盖率.
归档时间: |
|
查看次数: |
5962 次 |
最近记录: |