0

每次我尝试从没有 .select 的查询中映射 dto->entity 时,都会遇到相同的错误:

检索数据时出错。对象 [object Object] 的属性“entityAspect”不是函数

我正在使用 Breeze+Durandal 在 SPA 中工作,我的查询方法是:

var getTratamentoByPacienteId = function (pacienteId, tratamentoObservable) {
        var query = entityQuery.from('Tratamentos')
            .where('pacienteId', '==', pacienteId)
            .expand("Cardapios.Refeicoes.TipoRefeicao, Cardapios.Refeicoes.ItensRefeicao.Alimento, Cardapios.Refeicoes.ItensRefeicao.UnidadeMedida");

        var result = manager.executeQuery(query)
            .then(querySucceeded)
            .fail(queryFailed);
        return result;

        function querySucceeded(data) {
            var list = partialMapper.mapDtosToEntities(manager, data.results, entityNames.tratamento, 'id');
            if (tratamentoObservable) {
                tratamentoObservable(list[0]);
            }
            log('Retrieved [Tratamento] from remote data source', data, true);
            return tratamentoObservable;
        }
    };

    function mapDtosToEntities(manager, dtos, entityName, keyName, extendWith) {
        return dtos.map(dtoToEntityMapper);

        function dtoToEntityMapper(dto) {
            var keyValue = dto[keyName];
            var entity = manager.getEntityByKey(entityName, keyValue);
            if (!entity) {
                // We don't have it, so create it as a partial
                extendWith = $.extend({}, extendWith || defaultExtension);
                extendWith[keyName] = keyValue;
                entity = manager.createEntity(entityName, extendWith);
            }
            mapToEntity(entity, dto);
            entity.entityAspect.setUnchanged();
            return entity;
        }

        function mapToEntity(entity, dto) {
            // entity is an object with observables
            // dto is from json
            for (var prop in dto) {
                if (dto.hasOwnProperty(prop)) {
                    entity[prop](dto[prop]); /*<- Error here*/
                }
            }
            return entity;
        }
    }
4

2 回答 2

1

沃德的观点已经死了,但要回答你问题的第一部分

每次我尝试从没有 .select 的查询中映射 dto->entity 时,都会遇到相同的错误:

Breeze 使用 .select 语句返回的是投影(简单的 js 对象),而不是实体。在您的情况下,当您省略选择部分时,将返回一个实体(具有 entityAspect 属性)。

在您现有的情况下,您可以通过以下几种方式删除属性:

delete entity.entityAspect // remove directly

或通过 ko.mapping:

dto = ko.mapping.toJS(entity,{'ignore':['entityAspect']); // add any other props to ignore array

稍微偏离主题,但要记住另一件事,投影不会缓存在客户端上(但是,它们包含的任何实体都会缓存)。

于 2013-05-24T20:48:57.677 回答
1

我对你的意图感到困惑。的要点mapDtosToEntities是将投影数据(使用选择返回的数据)映射到实体中。您的查询已经返回实体!你为什么要映射它们?

不要将实体映射为 dto!

下面,如果你关心的话,这就是为什么代码会在它所在的地方爆炸的原因。

看看在mapToEntity做什么。它将假定 Dto 的每个值都对应到新创建的实体的同名属性中。假设dto只有选定属性的原始 JSON 服务器数据。

但在您的示例中,dto它实际上是一个Tratamento实体,其数据属性是 Knockout 函数,而不是原始数据值。您实际上是在将目标实体属性设置为函数!

你正在做这样的事情:

var fn = dto.name; // 这是 ko 可观察函数,而不是字符串!
tratamento.name(fn); // 您只需将名称设置为函数!

这根本不是你想要的。

KO不会阻止你,因为它真的不在乎你分配什么。也没有 JavaScript 语法问题,直到...

...dto属性循环 ( for (var prop in dto)...) 最终到达entityAspect属性。然后你会得到异常,因为你正在有效地这样做:

tratamento.entityAspect(dto.entityAspect);

tratamento.entityAspect是一个属性,而不是一个 KO 函数。

这就是错误消息所说的:

对象 [object Object] 的属性“entityAspect”不是函数

于 2013-05-24T03:06:04.610 回答