Breeze Partial初始化程序

时间:2013-05-06 18:23:22

标签: javascript asp.net knockout.js breeze

我有一个单页应用程序到目前为止工作得很好,但我遇到了一个我无法弄清楚的问题。我正在使用breeze来填充要在表格中显示的项目列表。有比我实际需要更多的信息,所以我正在对数据进行投影。我想在实体上添加一个计算结果。所以要完成这个我注册和实体构造函数就像这样......

metadataStore.registerEntityTypeCtor(entityNames.project, function () { this.isPartial = false; }, initializeProject);

initializeProject函数使用项目中的一些值来确定计算值应该是什么。例如,如果Project.Type ==“P”,则rowClass应为=“Red”。

我遇到的问题是Project的所有属性都是null,除了恰好是关键的ProjNum。我相信这个问题是因为我正在进行投影,因为我已经为其他类型注册了其他初始化器,它们工作得很好。有没有办法使这项工作?

编辑:我想我只想添加一些细节以便澄清。所有属性的值都设置为knockout observables,当我使用Chrome中的javascript调试器查询属性时,任何属性的_latestValue都为null。设置的唯一属性是ProjNum,它也是实体密钥。

EDIT2:这是执行投影的客户端代码

var getProjectPartials = function (projectObservable, username, forceRemote) {
    var p1 = new breeze.Predicate("ProjManager", "==", username);
    var p2 = new breeze.Predicate("ApprovalStatus", "!=", "X");
    var p3 = new breeze.Predicate("ApprovalStatus", "!=", "C");

    var select = 'ProjNum,Title,Type,ApprovalStatus,CurrentStep,StartDate,ProjTargetDate,CurTargDate';

    var isQaUser = cookies.getCookie("IsQaUser");

    if (isQaUser == "True") {
        p1 = new breeze.Predicate("QAManager", "==", username);
        select = select + ',QAManager';
    } else {
        select = select + ',ProjManager';
    }

    var query = entityQuery
        .from('Projects')
        .where(p1.and(p2).and(p3))
        .select(select);

    if (!forceRemote) {
        var p = getLocal(query);
        if (p.length > 1) {
            projectObservable(p);
            return Q.resolve();
        }
    }

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

    function querySucceeded(data) {
        var list = partialMapper.mapDtosToEntities(
            manager,
            data.results,
            model.entityNames.project,
            'ProjNum'
        );
        if (projectObservable) {
            projectObservable(list);
        }
        log('Retrieved projects using breeze', data, true);
    }
};

和partialMapper.mapDtosToEntities函数的代码。

var defaultExtension = { isPartial: true };

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) {
            extendWith = $.extend({}, extendWith || defaultExtension);
            extendWith[keyName] = keyValue;
            entity = manager.createEntity(entityName, extendWith);
        }
        mapToEntity(entity, dto);
        entity.entityAspect.setUnchanged();
        return entity;
    }

    function mapToEntity(entity, dto) {
        for (var prop in dto) {
            if (dto.hasOwnProperty(prop)) {
                entity[prop](dto[prop]);
            }
        }
        return entity;
    }
}

EDIT3:看起来这是我的错误。当我仔细观察initializeProject时,我发现了错误。下面是我修复它之前的功能。

function initializeProject(project) {
    project.rowClass = ko.computed(function() {
        if (project.Type == "R") {
            return "project-list-item info";
        } else if (project.Type == "P") {
            return "project-list-item error";
        }
        return "project-list-item";
    });
}

问题出在project.Type我应该使用project.Type(),因为它是一个可观察的。自从开始这个项目以来,我做了太多次这是一个愚蠢的错误。

EDIT4:在initializeProject中,有些部分正在运行而其他部分则没有。当我尝试访问project.ProjTargetDate()时,我得到null,与project.StartDate()相同。由于Null值,我从当前库中得到一个错误,因为我正在使用这些日期来确定项目何时迟到。我尝试从客户端查询和对部分实体映射器的调用中删除select,当我这样做时,一切正常。

1 个答案:

答案 0 :(得分:2)

你似乎越来越近了。我认为你initializeProject方法中的一些保护条款会有所帮助,在与Knockout合作时,人们总是在与括号问题作斗争。

顺便说一句,我强烈推荐Chrome的Knockout Context Debugger插件来诊断绑定问题。

尝试toType()

你正在努力完成你的DTO映射,并跟随他的课程中的John代码。从那时起,有一种将投影数据导入实体的新方法:将toType(...)添加到查询的末尾,如下所示:

var query = entityQuery
        .from('Projects')
        .where(p1.and(p2).and(p3))
        .select(select)
        .toType('Project'); // cast to Project

它无法解决所有问题,但您可以取消dto映射。

考虑服务器上的DTO

我应该首先指出这一点。如果您始终将此数据缩小到适当大小,为什么不定义面向客户端的模型以适合您的客户。在通过网络发送数据之前,创建正确形状的DTO类并在服务器上投影到它们中。

您还可以构建元数据以匹配这些DTO,以便客户端上的Project具有应该具有的属性......而不再有。

我现在正在写这个。在一周左右的时间内应该有一个页面。