1

我有 2 个具有 1:M 关系的实体。

Vehicle (Id, RetailPrice, StockOn, VehicleInfoId) and 
VehicleInfo (Id, Year, Make, Model, ICollection<Vehicle>)

两个 ID 都是用户指定的(字符串),但因为 Breeze 需要唯一的键(即使是临时的)我必须使用id = breeze.core.getUuid(). 此外,Year 和 RetailPrice 设置为 0(Year 是 int,RetailPrice 是小数)。

一旦我将这些实体绑定到“新车表单”,这些值就会立即显示给用户,而实际上我希望它们为空白......处理这个问题的最佳方法是什么?我的一些想法是:

  1. 添加其他属性(通过初始化程序)并使用这些属性绑定到表单上。然后就在保存之前,交换属性。
  2. 在初始化程序(而不是构造函数)中“清除”这些属性......
  3. 也许使用自定义 KO 绑定处理程序?

有没有更好的办法?

这是我到目前为止所拥有的(使用#2,但我不确定这是否正确)

/viewmodels/vehicleadd.js

var vehicle = ko.observable();
var viewModel = {
    title: 'Add New Vehicle',
    vehicle: vehicle,
};
return viewModel;
function activate() {
    vehicle(datacontext.createVehicle());
}

/services/datacontext.js

function init() {
    logger.debug(datacontext, 'Initializing data context...');
    return manager.fetchMetadata()
        .then(model.configureMetadataStore(manager.metadataStore))
        .then(model.applyValidators)
        //.then(loadLookups)
        .fail(initFailed);
}

function createVehicle() {
 var newVehicleInfo = manager.createEntity('VehicleInfo');
 var newVehicle = manager.createEntity('Vehicle');
 newVehicle.vehicleInfo(newVehicleInfo);

 return newVehicle;
}

/services/model.js

function configureMetadataStore(metadataStore) {
    logger.debug(model, 'Configuring metadata store...');
    extendVehicle(metadataStore);
    extendVehicleInfo(metadataStore);
}

function extendVehicle(metadataStore) {
    // --- custom constructor ---
    var vehicleCtor = function () {
        this.id = ko.observable(breeze.core.getUuid()); // must have for Breeze to work...
    };
    // --- initializer ---
    var vehicleInitializer = function (vehicle) {
        // defaults
        vehicle.id(null);                       // user to input
        vehicle.retailPrice(null);              // user to input
        vehicle.stockedOn(moment().format());   // set to current date & time
        // additional, non persisted properties
        vehicle.isBeingEdited = ko.observable(false);
        vehicle.isBeingSaved = ko.observable(vehicle.entityAspect.isBeingSaved);             
    };
    // --- register custom ctor & initializer ---
    metadataStore.registerEntityTypeCtor(EntityNames.Vehicle, vehicleCtor, vehicleInitializer);
}

function extendVehicleInfo(metadataStore) {
    // --- custom constructor ---
    var vehicleInfoCtor = function () {
        this.id = ko.observable(breeze.core.getUuid());
    };
    // --- initializer ---
    var vehicleInfoInitializer = function (vehicleInfo) {
        // defaults
        vehicleInfo.year = ko.observable(moment().format());
        // additional, non persisted properties
        vehicleInfo.isBeingEdited = ko.observable(false);
        vehicleInfo.isBeingSaved = ko.observable(vehicleInfo.entityAspect.isBeingSaved);
        // computed properties
        vehicleInfo.Description = ko.computed(function () {
            return vehicleInfo.year() + ' ' + vehicleInfo.make() + ' ' + vehicleInfo.model();
        });             
    };
    // --- register custom ctor & initializer ---
    metadataStore.registerEntityTypeCtor(EntityNames.VehicleInfo, vehicleInfoCtor, vehicleInfoInitializer);
}

更新#1

经过一些测试,看起来#2 在查询时不起作用。在(重新)阅读“扩展实体”文档(查找“实体创建序列”段落)之后,它特别指出在创建实体和查询的情况下,在两种情况下都会调用初始化函数。因此,初始化程序中的“清除” Id、RetailPrice 会中断查询和导入......

4

1 回答 1

1

我会考虑添加在初始化程序中计算的读/写敲除(KO)。

当值是 GUID ...或您设计的任何其他唯一临时值时,计算的“读取”端将返回空白。

“写入”端将 (a) 确认缓存中没有其他实体具有该键,然后 (b) 用新值覆盖该键。“读取”端现在将显示该值,因为它不再是“临时的”。

如果您在任何其他关联中使用这些键,您将处于一个受伤的世界;您必须手动修复它们……也许在您的 KO 计算写入逻辑中。

我假设您已经为用户输入的值与其他用户输入的数据库上的另一个键冲突的可能性做好了准备。

我将为您省去关于语义键的讲座(如“不要使用它们”);我认为一些遗留数据库会让你处于这个位置。

于 2013-06-05T19:02:24.677 回答