Knockout.js 使用typescript创建实体
我正在使用Breeze+Typescript+Knockout进行水疗,我面临以下问题: 当我使用EntityManager.createEntity创建新实体时,typescript不允许我使用Breeze从元数据生成的观察值。 Typescript“只看到”entityAspect和entityType属性。 我正在使用DefinitelyTyped的类型定义。 非常感谢您的帮助 看看: 您在ko上看到的功能(如可观察等)是在KnockoutStatic界面上定义的功能,因为这一行:Knockout.js 使用typescript创建实体,knockout.js,typescript,breeze,single-page-application,Knockout.js,Typescript,Breeze,Single Page Application,我正在使用Breeze+Typescript+Knockout进行水疗,我面临以下问题: 当我使用EntityManager.createEntity创建新实体时,typescript不允许我使用Breeze从元数据生成的观察值。 Typescript“只看到”entityAspect和entityType属性。 我正在使用DefinitelyTyped的类型定义。 非常感谢您的帮助 看看: 您在ko上看到的功能(如可观察等)是在KnockoutStatic界面上定义的功能,因为这一行: dec
declare var ko: KnockoutStatic;
以下是此接口的一个片段:
interface KnockoutStatic {
utils: KnockoutUtils;
memoization: KnockoutMemoization;
bindingHandlers: KnockoutBindingHandlers;
virtualElements: KnockoutVirtualElements;
extenders: KnockoutExtenders;
applyBindings(viewModel: any, rootNode?: any): void;
applyBindingsToDescendants(viewModel: any, rootNode: any): void;
applyBindingsToNode(node: Element, options: any, viewModel: any): void;
subscribable: KnockoutSubscribableStatic;
observable: KnockoutObservableStatic;
computed: KnockoutComputedStatic;
observableArray: KnockoutObservableArrayStatic;
.....
因此,如果您想在ko上使用新函数,则需要为KnockoutStatic接口定义新函数,例如:
interface KnockoutStatic {
yourFunc: KnockoutObservableStatic;
}
由于接口是开放式的,所以可以在多个文件中声明接口定义的各个部分。希望这有帮助 您可以为您的类型创建一个接口,该接口扩展了
breeze.Entity
:
/// <reference path="breeze.d.ts" />
module model {
export interface ResponsesItem extends breeze.Entity {
ContentTypeID: string;
Title: string;
Description: string;
EventDate: any;
/* etc. */
}
}
//
模块模型{
导出接口响应项扩展了breeze.Entity{
ContentTypeID:string;
标题:字符串;
描述:字符串;
事件日期:任何;
/*等等*/
}
}
然后,只要需要以类型化的方式使用对象,例如从服务器加载时的查询结果,就可以将对象强制转换到此接口:
private loadResponses(): void {
this.dataservice.ListResponses()
.then((data: { results: breeze.Entity[]; query: breeze.EntityQuery; XHR: XMLHttpRequest; }) => {
var results: model.ResponsesItem[] = <model.ResponsesItem[]>data.results;
// Do something with typed results array here.
}).fail((error) => {
this.handleDataError(error);
});
}
private loadResponses():void{
this.dataservice.ListResponses()
.then((数据:{results:breeze.Entity[];query:breeze.EntityQuery;XHR:XMLHttpRequest;})=>{
var结果:model.responseItem[]=data.results;
//在这里对类型化结果数组执行一些操作。
}).失败((错误)=>{
此.handleDataError(错误);
});
}
查看我的答案,在那里我黑了T4TS,吐出了支持Breeze的TS定义 下面是一个页面,您可以在站点中放置该页面来生成typescript接口定义。页面获取breeze元数据,然后遍历所有类型,并为每个类型输出一个typescript接口声明。然后可以将此页面的输出粘贴到任何类型脚本文件(*.ts)或类型脚本定义文件(*.d.ts)中。如果要命名接口的名称空间,请将结果包含在模块声明中:declare module northwind{…在此处粘贴接口…}
在使用页面之前,您需要进行一次编辑:将实体管理器的控制器url从“api/northwind”更改为breeze控制器的url
生成的接口依赖于Knockout.js typescript定义,您可以在此处获取这些定义:
使用中的northwind示例,此定义生成器页面的输出如下所示:
export interface Employee extends breeze.Entity {
FirstName: KnockoutObservable<string>;
LastName: KnockoutObservable<string>;
}
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);
});
导出接口Employee.Entity{
名字:KnockoutObservable;
姓氏:KnockoutObservable;
}
然后,您可以使用breeze执行查询,并将结果转换为一组员工,如下所示:
export interface Employee extends breeze.Entity {
FirstName: KnockoutObservable<string>;
LastName: KnockoutObservable<string>;
}
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);
});
var-manager=new breeze.EntityManager('api/northwind');
var query=new breeze.EntityQuery()
.来自(“员工”);
executeQuery.then(数据=>{
//***将结果强制转换为雇员的强类型数组***
var员工=数据。结果;
}).失败(e=>{
警报(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>
类型脚本定义生成器
代码{
空白:预处理;
}
$(文档).ready(函数(){
var entityManager=new breeze.entityManager('api/northwind');
entityManager.fetchMetadata()
.然后(函数(){
var html='',
types=entityManager.metadataStore.getEntityTypes(),
类型,
我
J
财产,,
crlf=String.fromCharCode(13),
代码=document.createElement('code'),
script=document.createElement('script');
函数getJSType(metadataType){
if(/(Int64)|(Int32)|(Int16)|(字节)|(十进制)|(双精度)|(单精度)|(数字)/.test(元数据类型))
返回“数字”;
else if(/(日期时间)|(日期时间偏移量)|(时间)|(日期)/.test(元数据类型))
返回“日期”;
else if(/(布尔)/i.test(元数据类型))
返回布尔值;
返回'string';
}
对于(i=0;i0)
继续;
html+=''+property.name;
//if(property.isNullable)
//html+='?';
html+=':KnockoutObservable';