Я настраиваю SPA, используя Angular и Breeze. Я следил за учебником Джона Папы по горячим полотенцам с сайта множественного числа. У меня странная проблема, думаю, которая может быть вызвана моими метаданными? Но в конце концов, я не совсем уверен....
Во-первых, мой API работает со стеком LAMP, поэтому я не использую EF. Я создал конечную точку метаданных, которая, как мне кажется, дает мне правильную структуру, которая мне нужна. Я использую breeze.angular.q.js, чтобы упростить свои сопоставления из Q до $q
ресурс: API/v1/метаданные
{
"metadataVersion": "1.0.5",
"dataServices": [
{
"serviceName": "api/v1/",
"hasServerMetadata": true,
"jsonResultsAdapter": "webApi_default",
"useJsonp": false
}
],
"structuralTypes": [
{
"shortName": "tracks",
"namespace": "MyNamespace",
"dataProperties": [
{
"name": "id",
"nameOnServer": "id",
"maxLength": 36,
"validators": [],
"dataType": "Guid",
"isPartOfKey": true
},
{
"name": "title",
"nameOnServer": "title",
"maxLength": 255,
"validators": [],
"dataType": "String"
},
{
"name": "description",
"nameOnServer": "description",
"maxLength": 0,
"validators": [],
"dataType": "String"
}
]
}
]
}
пример возвращаемых данных API выглядит следующим образом:
ресурс: API/v1/треки
{
"data": [
{
"id": "495f21d6-adfc-40b6-a41c-fc93d9275e24",
"title": "harum",
"description": "Error doloribus ipsam et sunt fugiat."
},
{
"id": "d7b141d2-6523-4777-8b5a-3d47cc23a0fe",
"title": "necessitatibus",
"description": "Voluptatem odit nulla maiores minima eius et."
}
],
"embeds": [
"courses"
]
}
Теперь со всем моим кодом я фактически возвращаю правильные данные из своего API. Я привел примеры с сайта breeze в виде нескольких хороших лакомых кусочков, которые я нашел здесь, на SO (понравился этот вопрос и отличный ответ от палаты). Увы, не повезло. По сути, что происходит, когда я пытаюсь перебрать свои результаты в моей модели представления, которые возвращаются из моего запроса бриза, я получаю угловую ошибку Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: t in vm.tracks, Duplicate key: object:00I
Вызов происходит в функции внутри моего контекста данных. Данные, возвращенные в моем обратном вызове обещания querySucceeded, не связаны правильно.
datacontext.js
...
function getTrackPartials() {
...
return EntityQuery.from(entityNames.track)
.toType(entityNames.track)
.using(manager).execute()
.then(querySucceeded, _queryFailed);
function querySucceeded(data) {
console.log(data); // <-- Log out to see what is returned
tracks = data.results;
_areTracksLoaded(true)
log('Retrieved [Track Partials] from remote data source', tracks.length, true);
return tracks;
}
}
Если бы я вывел эти данные на консоль, я бы получил это (все $$hashKey одинаковы, а идентификатор, заголовок и описание равны NULL. Но я получаю правильное количество результатов, а это не так). t совпадение - если я настраиваю количество результатов, которые я должен получить, оно каждый раз правильно совпадает).
Теперь, поскольку мои данные возвращаются немного другими, я использовал пример Эдмондса и создал custom JsonResultsAdapter
, чтобы я мог "массировать" данные. На данный момент это очень элементарно, так как я просто пытаюсь заставить это работать. Что действительно сбивает меня с толку, так это то, что если я выведу параметр node
из функции visitNode
в JsonResultsAdapter
, у него будут правильные данные....????
entityManagerFactory.js
(function () {
'use strict';
var serviceId = 'entityManagerFactory';
angular.module('app').factory(serviceId, ['config', emFactory]);
function emFactory(config) {
breeze.config.initializeAdapterInstance('modelLibrary', 'backingStore', true);
breeze.NamingConvention.camelCase.setAsDefault();
var serviceName = config.remoteServiceName;
var metadataStore = new breeze.MetadataStore();
var provider = {
metadataStore: metadataStore,
newManager: newManager
};
var jsonResultsAdapter = new breeze.JsonResultsAdapter({
name: "Tracks",
extractResults: function(json) {
console.log(json.results.data); // <-- Log out to see what is returned
return json.results.data;
},
visitNode: function(node, mappingContext, nodeContext) {
console.log(node); // <-- Log out to see what is returned
return {
entityType: 'tracks',
nodeId: node.id
};
}
});
var dataService = new breeze.DataService({
serviceName: serviceName,
jsonResultsAdapter: jsonResultsAdapter
});
return provider;
function newManager() {
var mgr = new breeze.EntityManager({
dataService: dataService,
metadataStore: metadataStore
});
return mgr
}
}
})();
Вот мое возвращаемое значение из моей функции JsonResultsAdapter::extractResults
Вот узел из моей функции JsonResultsAdapter::visitNode
Любая помощь будет оценена по достоинству. Как я уже сказал, я не совсем уверен, где происходит ошибка? Но если бы мне пришлось угадывать, я бы сказал, что между моим EntityQuery, использующим мой менеджер, и JsonResultsAdapter есть некоторая связь, которая может быть вызвана плохими метаданными, которые я сгенерировал.
** ОБНОВЛЕНИЕ **
Итак, я прошелся по коду бриза, чтобы выяснить, где я теряю свои данные, и смог выяснить, что происходит, и способ это исправить. Однако я не уверен, что это лучший способ справиться с этим.
Я должен упомянуть, что я использовал Bower для установки breeze — и, сделав это, я выбрал пакет bower-breeze-angular git://github.com/eggers/bower-breeze-angular.git
, а не стандартный breeze breeze git://github.com/IdeaBlade/Breeze.git
, который раздут с примерами и другими данными, которые я не хотел упаковывать в свой репозиторий.
Короче говоря, после того, как мой обратный вызов JsonResultsAdapter::visitnode
вернулся, ему нужно "объединить" мои данные, у меня проблема с entityKey, возвращаемый моим узлом, не совпадает. Это связано с тем, что rawValueFn из моего mappingContext
ищет nameOnServer
, который, как я думал, установил в своих метаданных с моего сервера, но каким-то образом, когда я выхожу из системы, свойство данных изменилось по сравнению с тем, что я установил.
Это один dp, вышедший из системы, если вы посмотрите вверх в моем вызове ресурсов метаданных, я специально установил это на «id». Как это изменилось на Id? Вот что вызывает у меня головную боль!
Я могу обойти это, обновив мою функцию rawValueFn в моем mapContext в моем JsonResultsAdapter
, и все будет работать, но это похоже на «хак». Я также пробовал играть с «NamingConvention», но это тоже не работает.
Вот мой обновленный JsonFactory, который заставляет его работать
var jsonResultsAdapter = new breeze.JsonResultsAdapter({
name: "Tracks",
extractResults: function(json) {
return json.results.data;
},
visitNode: function(node, mappingContext, nodeContext) {
// Had to adjust this so it would lowercase and correctly match
mappingContext.rawValueFn = function(rawEntity, dp) {
name = dp.name;
name.substring(0, 1).toLowerCase() + name.substring(1);
return rawEntity[name];
}
return {
entityType: 'tracks'
};
}
});
extractResults
. Убедитесь, чтоjson.results.data
это то, что вы думаете. ФункцияextractResults
должна возвращать массив. - person Steve Schmitt   schedule 13.02.2014extractResults
. Он внизу, ближе к низу поста. На самом деле я возвращаю массив из двух объектов, и прямо под этим изображением вы можете видеть, когда яvisitNode
получаю правильный объект с правильными данными... не уверен, почему он не объединяется правильно при возврате из этой функции? - person veilig   schedule 13.02.2014