Skip to content

ViewModel Configuration

A crucial part of the generated TypeScript ViewModels that Coalesce creates for you is the hierarchical configuration system that allows coarse-grained or fine-grained control over their behaviors.

Hierarchy

The configuration system has four levels where configuration can be performed, structured as follows:

Root Configuration

Coalesce.GlobalConfiguration: ModelConfiguration<any>
Coalesce.GlobalConfiguration.app: AppConfiguration

The root configuration contains all configuration properties which apply to class category (TypeScript ViewModels, TypeScript ListViewModels, and Services). The app property contains global app configuration that exists independent of any models. Then, for each class kind, the following are available:

Root ViewModel/ListViewModel Configuration

Coalesce.GlobalConfiguration.viewModel: ViewModelConfiguration<BaseViewModel>
Coalesce.GlobalConfiguration.listViewModel: ListViewModelConfiguration<BaseListViewModel<BaseViewModel>, BaseViewModel>
Coalesce.GlobalConfiguration.serviceClient: ServiceClientConfiguration<ServiceClient>

Additional root configuration objects exist, one for each class kind. These configuration objects govern behavior that applies to only objects of these types. Root configuration can be overridden using these objects, although the practicality of doing so is dubious.

Class Configuration

ViewModels.ClassName.coalesceConfig: ViewModelConfiguration<ViewModels.ClassName>
ListViewModels.ClassNameList.coalesceConfig: ListViewModelConfiguration<ListViewModels.ClassNameList, ViewModels.ClassName>
Services.ServiceNameClient.coalesceConfig: ServiceClientConfiguration<ServiceName>

Each class kind has a static property named coalesceConfig that controls behavior for all instances of that class.

Instance Configuration

instance.coalesceConfig: ViewModelConfiguration<ViewModels.ClassName>
listInstance.coalesceConfig: ListViewModelConfiguration<ListViewModels.ClassNameList, ViewModels.ClassName>
serviceInstance.coalesceConfig: ServiceClientConfiguration<ServiceName>

Each instance of these classes also has a coalesceConfig property that controls behaviors for that instance only.

Evaluation

All configuration properties are Knockout ComputedObservable<T> objects. These observables behave like any other observable - call them with no parameter to obtain the value, call with a parameter to set their value.

Whenever a configuration property is read from, it first checks its own configuration object for the value of that property. If the explicit value for that configuration object is null, the parent's configuration will be checked for a value. This continues until either a value is found or the root configuration object is reached.

When a configuration property is given a value, that value is established on that configuration object only. Any dependent configuration objects will not be modified, and if those dependent configuration objects already have a value for that property, their existing value will be used unless that value is later set to null.

To obtain the raw value for a specific configuration property, call the raw() method on the observable: model.coalesceConfig.autoSaveEnabled.raw().

Available Properties & Defaults

The following configuration properties are available. Their default values are also listed. Note that all configuration properties are observables, but for simplicity the documentation below lists the underlying type.

Root Configuration

These properties on Coalesce.GlobalConfiguration are available to both ViewModelConfiguration, ListViewModelConfiguration, and ServiceClientConfiguration.

baseApiUrl: string = '/api'

The relative url where the API may be found.

baseViewUrl: string = ''

The relative url where the admin views may be found.

showFailureAlerts: boolean = true

Whether or not the callback specified for onFailure will be called or not.

onFailure: (obj, message) => alert(message)

A callback to be called when a failure response is received from the server.

onStartBusy: obj => Coalesce.Utilities.showBusy()

A callback to be called when an AJAX request begins.

onFinishBusy: obj => Coalesce.Utilities.hideBusy()

A callback to be called when an AJAX request completes.

App Configuration

These properties on Coalesce.GlobalConfiguration.app are not hierarchical - they govern the entire Coalesce application:

select2Theme: string | null = null

The theme parameter to select2's constructor when called by Coalesce's select2 Knockout Bindings.

ViewModelConfiguration

saveTimeoutMs: number = 500

Time to wait after a change is seen before auto-saving (if autoSaveEnabled is true). Acts as a debouncing timer for multiple simultaneous changes.

saveIncludedFields: string[] | null = null

An array of property names that, if set, will determine which fields will be sent to the server when saving. Only those values that are actually sent to the server will be mapped to the underlying entity.

This can improves the handling of concurrent changes being made by multiple users against different fields of the same entity. Specifically, if one page is designed to edit fields A and B, and another page is designed for editing fields C and D, you can configure this setting appropriately on each page to only save the corresponding fields.

Due to design limitations, this cannot be determined dynamically like it can with Vue's $saveMode property

WARNING

Surgical saves require DTOs on the server that are capable of determining which of their properties have been set by the model binder, as surgical saves are sent from the client by entirely omitting properties from the x-www-form-urlencoded body that is sent to the server.

The Generated C# DTOs implement the necessary logic for this; however, any Custom DTOs must have this logic manually written by you, the developer. Either implement the same pattern that can be seen in the Generated C# DTOs, or do not use surgical saves with Custom DTOs.

autoSaveEnabled: boolean = true

Determines whether changes to a model will be automatically saved after saveTimeoutMs milliseconds have elapsed.

autoSaveCollectionsEnabled: boolean = true

Determines whether or not changes to many-to-many collection properties will automatically trigger a save call to the server or not.

showBusyWhenSaving: boolean = false

Whether to invoke onStartBusy and onFinishBusy during saves.

loadResponseFromSaves: boolean = true

Whether or not to reload the ViewModel with the state of the object received from the server after a call to .save().

validateOnLoadFromDto: boolean = true

Whether or not to validate the model after loading it from a DTO from the server. Disabling this can improve performance in some cases.

setupValidationAutomatically: boolean = true

Whether or not validation on a ViewModel should be setup in its constructor, or if validation must be set up manually by calling viewModel.setupValidation(). Turning this off can improve performance in read-only scenarios.

onLoadFromDto: null | ((object: T) => void) = null

An optional callback to be called when an object is loaded from a response from the server. Callback will be called after all properties on the ViewModel have been set from the server response.

initialDataSource: null | DataSource<T> | (new () => DataSource<T>) = null

The dataSource (either an instance or a type) that will be used as the initial dataSource when a new object of this type is created. Not valid for global configuration; recommended to be used on class-level configuration. E.g. ViewModels.MyModel.coalesceConfig.initialDataSource(MyModel.dataSources.MyDataSource);

ListViewModelConfiguration

No special configuration is currently available for ListViewModels.

ServiceClientConfiguration

No special configuration is currently available for ServiceClients.


Coalesce is a free and open-source framework created by IntelliTect to fill our desire to create better apps, faster. IntelliTect is a high-end software architecture and development consulting firm based in Spokane, Washington.

If you're looking for help with your software project, whether it be a Coalesce application, other technologies, or even just an idea, reach out to us at info@intellitect.com — we'd love to start a conversation! Our clients range from Fortune 100 companies to local small businesses and non-profits.