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....