Я использую Breeze + Typcript + Knockout для Spa, и перед этим сталкиваюсь со следующей проблемой: , когда я создаю новый объект с EntityManager.createEntity, машинопись не позволяет использовать наблюдаемые что Бриз генерируется из метаданных. Typcript «видит» только свойства «entityAspect» и «entityType». Я использую определения типов DefinitelyTyped. Любая помощь очень ценится!Breeze entity с машинописными текстами
ответ
Глядя на: https://github.com/borisyankov/DefinitelyTyped/blob/master/knockout/knockout.d.ts
функций, которые вы видите на кё (например, наблюдаемым и т.д.) являются функции, определенные на KnockoutStatic интерфейс из-за этой линии:
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. */
}
}
Вы можете бросить свои объекты к этому интерфейсу всякий раз, когда вам нужно работать с ними в типизированной образом, например, в результате запрос при загрузке с сервера:
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);
});
}
Спасибо JcFx, звучит хорошо! Попробуй это и отчитайся :-) PS: Что делать, если у меня есть несколько моделей, отправленных разными запросами Breeze? – frenchfaso
Несколько интерфейсов? – frenchfaso
Я не совсем уверен, что вы просите, но да. У меня есть отдельный метод для моего клиентского пакета данных для каждого типа, поэтому я знаю, чего я ожидаю от конкретного вызова, и могу использовать его соответствующим образом. Имейте в виду, что свойство интерфейса может быть другим интерфейсом, поэтому вы можете иметь структурированную, типизированную модель. Также ознакомьтесь с полезным шаблоном T4 от Christoffer для создания интерфейсов со своих серверных классов: https://github.com/cskeppstedt/t4ts – JcFx
Проверьте мой ответ на Breeze.js typed entities, где я взломал T4TS выплюнуть TS определения, которые поддерживают Breeze.
Ниже приведена страница, которую вы можете добавить на свой сайт, чтобы создавать определения интерфейсов типов. Страница извлекает метаданные бриза, а затем выполняет итерацию по всем типам и выводит декларацию интерфейса типов для каждого типа. Результат этой страницы можно вставить в любой файл машинописного файла (* .ts) или файл описания машинописных файлов (* .d.ts). Примените результаты в объявлении модуля, если вы хотите, чтобы пространство импортозаместимых интерфейсов: declare module northwind { ... paste interfaces here... }
.
Прежде чем использовать эту страницу, вам нужно будет сделать одно изменение: измените URL-адрес контроллера сущности менеджера «api/northwind» на любой URL-адрес вашего контроллера.
сгенерированных интерфейсы имеет зависимость от определений машинописи Knockout.js, которые вы можете захватить здесь: https://github.com/borisyankov/DefinitelyTyped/tree/master/knockout/
Использование Northwind примера из learn.breezejs.com, выхода этой страницы генератора определения будет что-то вроде этого:
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);
});
ниже - страница генераторов определений - добавьте новый 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>
Hy, спасибо за Ваш ответ. Я не уверен, что это решит мою проблему, которая является TypeScript неспособным поймать динамическую природу Breeze Entities. – frenchfaso