有没有一种方法可以像JaySvcUtil为JayData工作一样,使用Breeze创建类型化实体?这包括Typescript支持吗?Breeze框架中是否有通用的Typescript支持?
此要点包含T4TS的修改版本,该版本包含对生成"每个实体的设计时Javascript类"的一些初始支持,并支持Breeze。
https://gist.github.com/alexdresko/5393155
到目前为止,它符合我的需求。我确信你需要在你的解决方案中有明确类型的微风定义才能正常工作。
也许这是可以永久添加到T4TS的东西?也许这是微风队应该考虑的事情?或者也许这只是愚蠢的,除了我之外,对任何人都不起作用。:)
在我的数据服务中,我可以做一些类似的事情:
createOrganization() : T4TS.Organization {
return <T4TS.Organization>this.manager.createEntity("Organization");
}
然后,在我的VM中,所有这些代码都是很好的类型安全的。。
organizationSubmit() {
this.editingOrganization(false);
var newOrganization = this.dataservice.createOrganization();
newOrganization.Name(this.organizationNameInput());
if (newOrganization.entityAspect.validateEntity()) {
this.extendOrganization(newOrganization);
this.organizations.push(newOrganization);
this.dataservice.saveChanges();
this.organizationNameInput("");
} else {
this.handleItemErrors(newOrganization);
}
};
我真的不知道从这里开始该怎么办。我试着分叉T4TS,但没有时间弄清楚他的构建系统。因此得出了要点。意见当然是受欢迎的。
我们确实计划用TypeScript做更多的工作,但还没有确定具体的时间框架。(约翰的帖子中提到,鲍里斯的工作无疑是一个良好的开端)。
更新:自v0.84.4起,Breeze提供完整的TypeScript支持
至于为每个实体自动生成设计时Javascript类;我们已经就此进行了几次内部讨论,但我们真的在等着看社区投票支持什么。我们几乎肯定会在某个时候解决这个问题,但您在
UserVoice上的投票肯定会加快这个过程。
下面是一个页面,您可以将其放在站点中生成typescript接口定义。页面获取微风元数据,然后遍历所有类型,并为每个类型输出typescript接口声明。然后,可以将此页面的输出粘贴到任何类型脚本文件(*.ts)或类型脚本定义文件(*.d.ts)中。如果要为接口命名名称,请将结果封装在模块声明中:declare module northwind { ... paste interfaces here... }
。
在使用该页面之前,您需要进行一次编辑:将实体管理器的控制器url从"api/nothwind"更改为微风控制器的url。
生成的接口依赖于Knockout.js类型脚本定义,您可以在此处获取这些定义:https://github.com/borisyankov/DefinitelyTyped/tree/master/knockout/
使用learn.breezejs.com中的northwind示例,此定义生成器页面的输出如下所示:
export interface Employee extends breeze.Entity {
FirstName: KnockoutObservable<string>;
LastName: KnockoutObservable<string>;
}
然后,您可以使用breeze执行查询,并将结果投射给一组员工,如下所示:
var manager = new breeze.EntityManager('api/northwind');
var query = new breeze.EntityQuery()
.from("Employees");
manager.executeQuery(query).then(data => {
// ***cast the results to a strongly typed array of Employee***
var employees = <Employee[]>data.results;
}).fail(e => {
alert(e);
});
下面是定义生成器页面-将一个名为"definitions.html"的新html文件添加到您的项目中,运行该项目并导航到该页面。
<html>
<head>
<title>Typescript Definition Generator</title>
<style>
code {
white-space: pre;
}
</style>
<script src="//code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/knockout/knockout-3.0.0.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/q.js/1.0.0/q.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/breezejs/1.4.4/breeze.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var entityManager = new breeze.EntityManager('api/northwind');
entityManager.fetchMetadata()
.then(function () {
var html = '',
types = entityManager.metadataStore.getEntityTypes(),
type,
i,
j,
property,
crlf = String.fromCharCode(13),
code = document.createElement('code'),
script = document.createElement('script');
function getJSType(metadataType) {
if (/(Int64)|(Int32)|(Int16)|(Byte)|(Decimal)|(Double)|(Single)|(number)/.test(metadataType))
return 'number';
else if (/(DateTime)|(DateTimeOffset)|(Time)|(Date)/.test(metadataType))
return 'Date';
else if (/(Boolean)/i.test(metadataType))
return 'boolean';
return 'string';
}
for (i = 0; i < types.length; i++) {
// type declaration
var type = types[i];
html += 'export interface ' + type.shortName;
// base type
html += ' extends ';
if (type.hasOwnProperty('baseEntityType')) {
html += type.baseEntityType.shortName;
} else {
html += 'breeze.Entity';
}
html += ' {' + crlf;
// data properties
for (j = 0; j < type.dataProperties.length; j++) {
property = type.dataProperties[j];
if (type.baseEntityType && type.baseEntityType.dataProperties.filter(function (p) { return p.name === property.name; }).length > 0)
continue;
html += ' ' + property.name;
//if (property.isNullable)
// html += '?';
html += ': KnockoutObservable<';
html += getJSType(property.dataType.name);
html += '>; //' + property.dataType.name + crlf;
}
// navigation properties
for (j = 0; j < type.navigationProperties.length; j++) {
property = type.navigationProperties[j];
if (type.baseEntityType && type.baseEntityType.navigationProperties.filter(function (p) { return p.name === property.name; }).length > 0)
continue;
html += ' ' + property.name;
//if (property.isNullable)
// html += '?';
if (property.isScalar)
html += ': KnockoutObservable<';
else
html += ': KnockoutObservableArray<';
html += property.entityType.shortName;
html += '>;' + crlf;
}
html += '}' + crlf + crlf;
}
code.innerHTML = html;
$(code).addClass('prettyprint');
document.body.appendChild(code);
script.setAttribute('src', '//google-code-prettify.googlecode.com/svn/loader/run_prettify.js');
document.body.appendChild(script);
})
.fail(function (reason) {
alert(reason);
});
});
</script>
</head>
<body>
</body>
</html>
对于breeze TypeScript定义,请使用NuGet包breeze。TypeScript.DefinitelyTyped。若要为实体创建定义,可以使用TypeLITE。它将创建一个.d.ts
文件,其接口如下:
declare module MyProject.Models {
interface Customer {
Id: number;
AccountNumber: string;
...
虽然这些接口完全描述了您的实体,但它们并没有扩展breeze.Entity
。为了很好地使用Breeze API类型定义,您可以从中派生自己的接口,如下所示:
import Models = MyProject.Models;
interface Customer extends Models.Customer, breeze.Entity { }
...
这仍然需要一些手动编码,但至少它只针对每个类型,而不是针对每个属性。
关于Typescript,它肯定在我们的雷达上。我们至少会创建一个TypeScript"declare"文件,以便在使用Breeze时实现更好的智能感知。
你可以在UserVoice上投票。
在那之前,你可能想使用支持Breeze的Boris Yankov的绝对类型。
我的两分钱。。。
我一直在使用定义类型的定义文件为微风,它似乎工作得很好。
创建一个T4脚本为.edmx中的所有实体生成.d.ts文件非常简单,然后您就可以获得所需的intellisense了。如果Ward喜欢,我可以在某个地方发布一个T4脚本示例。