Model Layer¶
The model layer, generated as models.g.ts, contains a set of TypeScript interfaces that represent each client-exposed type in your data model. Each interface contains all the Properties of that type, as well as a $metadata
property that references the metadata object for that type. Enums and Data Sources are also represented in the model layer.
The model layer also includes a TypeScript class for each type that can be used to easily instantiate a valid implementation of its corresponding interface. However, it is not necessary for the classes to be used, and all parts of Coalesce that interact with the model layer don't perform any instanceof checks against models - the $metadata
property is used to determine type identity.
Concepts¶
The model layer is fairly simple - the only main concept it introduces on top of the Metadata Layer is the notion of interfaces and enums that mirror the C# types in your data model. As with the Metadata Layer, the source code of coalesce-vue is a great documentation supplement to this page.
Model¶
An interface describing an instance of a class type from your application's data model. All Model interfaces contain members for all the Properties of that type, as well as a $metadata
property that references the metadata object for that type.
DataSource¶
A class-based representation of a Data Source containing properties for any of the Custom Parameters of the data source, as well as a $metadata
property that references the metadata object for the data source.
Data sources are generated as concrete classes in a namespace named DataSources
that is nested inside a namespace named after their parent model type. For example:
import { Person } from '@/models.g'
const dataSource = new Person.DataSources.NamesStartingWith;
dataSource.startsWith = "A";
// Provide the dataSource to an API Client or a ViewModel...
Model Functions¶
The following functions exported from coalesce-vue
can be used with your models:
bindToQueryString(vue: Vue, obj: {}, key: string, queryKey: string = key, parse?: (v: any) => any, mode: 'push' | 'replace' = 'replace')
Binds property
key
ofobj
to query string parameterqueryKey
. When the object's value changes, the query string will be updated using vue-router. When the query string changes, the object's value will be updated.The query string will be updated using either
router.push
orrouter.replace
depending on the value of parametermode
.If the query string contains a value when this is called, the object will be updated with that value immediately.
If the object being bound to has
$metadata
, information from that metadata will be used to serialize and parse values to and from the query string. Otherwise,String(value)
will be used to serialize the value, and theparse
parameter (if provided) will be used to parse the value from the query string.import { bindToQueryString } from 'coalesce-vue'; // In the 'created' Vue lifecycle hook on a component: created() { // Bind pagination information to the query string: bindToQueryString(this, this.listViewModel.$params, 'pageSize', 'pageSize', v => +v); // Assuming the component has an 'activeTab' data member: bindToQueryString(this, this, 'activeTab'); }
bindKeyToRouteOnCreate(vue: Vue, model: Model<ModelType>, routeParamName: string = 'id', keepQuery: boolean = false)
When
model
is created (i.e. its primary key becomes non-null), replace the current URL with one that includes uses primary key for the route parameter named byrouteParamName
.The query string will not be kept when the route is changed unless
true
is given tokeepQuery
.import { bindKeyToRouteOnCreate } from 'coalesce-vue'; // In the 'created' Vue lifecycle hook on a component: created() { if (this.id) { this.viewModel.$load(this.id); } else { bindKeyToRouteOnCreate(this, this.viewModel); } }
Note
The route will be replaced directly via the HTML5 History API such that vue-router will not observe the change as an actual route change, preventing the current view from being recreated if a path-based key is being used on the application's
<router-view>
component.
Advanced Model Functions¶
The following functions exported from coalesce-vue
can be used with your models.
Note
These functions are used to implement the higher-order layers in the Vue stack.
While you're absolutely free to use them in your own code and can rely on their interface and behavior to remain consistent, you will find that you seldom need to use them directly - that's why we've split them into their own section here in the documentation.
convertToModel(value: any, metadata: Value | ClassType): any
Given any JavaScript value
value
, convert it into a valid implementation of the value or type described bymetadata
.For metadata describing a primitive or primitive-like value, the input will be parsed into a valid implementation of the correct JavaScript type. For example, for
metadata
that describes a boolean, a string"true"
will return a booleantrue
, and ISO 8601 date strings will result in a JavaScriptDate
object.For metadata describing a type, the input object will be mutated into a valid implementation of the appropriate model interface. Missing properties will be set to null, and any descendent properties of the provided object will be recursively processed with
convertToModel
.If any values are encountered that are fundamentally incompatible with the requested type described by the metadata, an error will be thrown.
mapToModel(value: any, metadata: Value | ClassType): any
- Performs the same operations as
convertToModel
, except that any objects encountered will not be mutated - instead, a new object or array will always be created. mapToDto(value: any, metadata: Value | ClassType): any
Maps the input to a representation suitable for JSON serialization.
Will not serialize child objects or collections whose metadata includes dontSerialize. Will only recurse to a maximum depth of 3.
modelDisplay(model: Model, options?: DisplayOptions): string
Returns a string representing the
model
suitable for display in a user interface.Uses the
displayProp
defined on the object's metadata. If nodisplayProp
is defined, the object will be displayed as JSON. The display prop on a model can be defined in C# with [ListText].See DisplayOptions for available options.
propDisplay(model: Model, prop: Property | string, options?: DisplayOptions): string
Returns a string representing the specified property of the given object suitable for display in a user interface.
The property can either be a string, representing one of the model's properties, or the actual
Property
metadata object of the property.See DisplayOptions for available options.
valueDisplay(value: any, metadata: Value, options?: DisplayOptions): string
Returns a string representing the given value (described by the given metadata).
See DisplayOptions for available options.
DisplayOptions¶
The following options are available to functions in coalesce-vue that render a value or object for display:
format
Options to be used when formatting a date. One of:
string
A UTS#35 date format string, to be passed to date-fns's format function.
Defaults to
"M/d/yyyy"
for date-only dates (specified with [DateType]), or"M/d/yyyy h:mm:ss aaa"
otherwise.{ distance: true; addSuffix?: boolean; includeSeconds?: boolean; }
Options to be passed to date-fns's formatDistanceToNow function.
Note
Values rendered with
formatDistanceToNow
function into a Vue component will not automatically be updated in realtime. If this is needed, you should use a strategy like using a key that you periodically update to force a re-render.
collection: { enumeratedItemsMax?: number, enumeratedItemsSeparator?: string }
- Options to be used when formatting a collection.