问题
I have 2 entites with 1:M relationship.
Vehicle (Id, RetailPrice, StockOn, VehicleInfoId) and
VehicleInfo (Id, Year, Make, Model, ICollection<Vehicle>)
Both Ids are user specified (strings) but because Breeze requires unique keys (even if temporary) I have to create entities with id = breeze.core.getUuid()
.
Furthermore, Year and RetailPrice are set to 0 (Year is an int, RetailPrice is decimal).
Once I bind these entities to a "New Vehicle form" these values are immediatelly shown to the user, when in fact I want them to be blank... What is the best way to handle this? Some ideas I have are:
- add additional properties (via initializer) and use those to bind on the form. Then just before the save, swap the properties.
- "wipe out" these properties in the initializer (not the constructor)....
- use custom KO binding handler maybe?
Is there a better way?
Here is what I have so far (using #2, but I am not sure if this is right)
/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);
}
Update #1
After some testing, looks like #2 will not work when querying. After (re) reading the "Extending Entities" doc (look for "Entity creation sequence" paragraph), it specifically says that initializer function is invoked in both cases, when entity is created and in case of querying. So "wiping out" Ids, RetailPrice in initializer breaks querying and importing....
回答1:
I would look into adding a read/write Knockout (KO) computed in the initializer.
The "read" side of the computed would return blank when the value is a GUID ... or any other unique temporary value you devise.
The "write" side would (a) confirm that no other entity in cache had that key and then (b) overwrite the key with the new value. The "read" side would now display that value because it is no longer "temporary".
You're in a world of hurt if you are using these keys in any other associations; you'll have to fix them up manually ... perhaps inside your KO computed write logic.
I assume you are already prepared for the possibility that the user-entered value collides with another key on the database, entered by some other user.
I will spare you the lecture on semantic keys (as in "don't use them"); I figure some legacy database put you in this spot.
来源:https://stackoverflow.com/questions/16928767/entitymanager-createentity-strategies-for-showing-generated-ids-and-default