You can use a component to replace or extend how a ViewModel column is rendered in a Turnkey client; this page helps MDriven developers choose the right component approach before they implement it.
What a component is in MDriven
In MDriven, a component is a reusable client-side user-interface implementation that renders in a Turnkey application. You assign it to a ViewModel column when the standard generated control does not provide the required presentation or interaction.
For example, you may replace a generic column's standard editor with:
- a chart that displays values supplied by the ViewModel;
- a multiple-file upload control;
- an HTML5 visualisation such as a map, board, or 3D object; or
- a custom table that displays a collection without the standard actions and selections.
The component receives its context from the ViewModel. Make every value that the component needs available in that ViewModel. A chart, for example, can use visible data columns and also columns whose Visible expression is false when those hidden columns supply chart data.
Choose the component technology
Turnkey has separate component approaches for its AngularJS and Blazor clients. Choose the approach that matches the client framework you are customizing; the file structures and implementation models are different.
| Client framework | Use this approach | When to use it |
|---|---|---|
| AngularJS | EXT Components | You want to provide HTML, CSS, and JavaScript/TypeScript in the Turnkey application's EXT_Components assets folder.
|
| Blazor | EXT ComponentsBlazor | You want to inject a Blazor WebAssembly component on a tagged ViewModel column. |
Do not treat an AngularJS EXT Component as a Blazor component, or the reverse. Follow the framework-specific page for required files, build output, and parameters.
Use a component on a ViewModel column
For an AngularJS EXT Component, the component name connects the ViewModel column to a folder in EXT_Components.
- In MDriven Designer, select the ViewModel column that will show the custom control. A generic column is useful when the component is not editing a normal model attribute.
- Set the column's UI override as required for the intended replacement.
- Add the tagged value
Angular_Ext_Componentto the column. - Set the tagged value's value to the component name.
- Create an
EXT_Components/<component name>folder with the matching name in the Turnkey application assets. - Add the files required by EXT Components, including the required
<component name>.cshtmlcontent file. - Run the application and verify that the column renders your component.
The name must match exactly. If the tagged value says PerformanceChart, create the corresponding EXT_Components/PerformanceChart folder and component files. A mismatch means Turnkey cannot find the component.
Keep the ViewModel and component contract explicit
A component is reusable when its required ViewModel data and actions are deliberate and named consistently.
For example, a file-upload component can use a generic upload-button column as its rendered location, temporary ViewModel columns for the uploaded file and file name, and a ViewModel action to create and attach each uploaded object. The full working pattern, including the required names that the example component references, is documented in Multiple file upload component.
For an AngularJS replacement control that binds to a ViewModel column, the binding can use the generated column runtime name:
<input ng-model='data.[ViewModelColumnName]'/>
When Turnkey compiles the override HTML, it can replace [ViewModelColumnName] with the runtime name of the column where the component is used. The related placeholders [ViewModelClassName] and [ViewModelColumnLabel] support reusable bindings and labels. See EXT Components for the replacement rules and implementation details.
Design and test custom components
Use these practices when building a component:
- Keep the component focused on rendering and interaction. Put application state, data, and business behavior in the ViewModel and its actions.
- Expose every data value the component needs through the ViewModel. Do not rely on a column being visible to make its data available.
- Use the ViewModel column's designed label when the component should display the same label as the generated UI.
- Give component CSS specific, maintainable selectors. Follow CSS BEM when styling Turnkey controls and their modifiers.
- Test the component where it will be used: with empty data, with populated data, and after ViewModel data changes.
- Check browser developer tools when JavaScript initialization or bindings do not behave as expected. An AngularJS directive runs when Angular connects markup and data, including when additional directive elements are created.
A local Turnkey prototyper session can detect a model-file change and reload the application. This makes it practical to change a tagged value or component implementation, reload, and confirm that the intended custom control replaces the standard editor.
Examples and implementation guides
Start with the guide that matches the result you need rather than copying unrelated component code.
| Goal | Guide |
|---|---|
| Build an AngularJS component with HTML, CSS, and JavaScript or TypeScript | EXT Components |
| Inject a Blazor WebAssembly component on a tagged ViewModel column | EXT ComponentsBlazor |
| Render Google Charts from ViewModel data | Using Google Charts |
| Upload several files from one component | Multiple file upload component |
| Render a collection as a minimal custom table | A simple table component for just listing a collection |
| Explore HTML5 component development examples | Turnkey sample Board Map Balls Gantt |
