Using Unions Instead of Base Classes
Inheritance is a part of internal implementation. You should not rely on the knowledge of relationships between base classes and their descendants. For generalization, use a union to define your own type.
For example, if you need a type for properties of multiple editor components, define the following union:
jQuery
type EditorProps = DxTextAreaTypes.Properties | DxTextBoxTypes.Properties | DxAutocompleteTypes.Properties | DxLookupTypes.Properties;
Angular
type EditorProps = DxTextAreaTypes.Properties | DxTextBoxTypes.Properties | DxAutocompleteTypes.Properties | DxLookupTypes.Properties;
Vue
type EditorProps = DxTextAreaTypes.Properties | DxTextBoxTypes.Properties | DxAutocompleteTypes.Properties | DxLookupTypes.Properties;
React
type EditorProps = TextAreaTypes.Properties | TextBoxTypes.Properties | AutocompleteTypes.Properties | LookupTypes.Properties;
Generic Parameters
Some types are generic. This is mostly the case for data-aware component types, such as DataGrid:
Angular
import { Component, ViewChild } from '@angular/core'; import { DxDataGridComponent, DxDataGridTypes } from 'devextreme-angular/ui/data-grid'; import { Employee } from './data'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { @ViewChild(DxDataGridComponent) dataGrid!: DxDataGridComponent<Employee, number>; onEditorPreparing(e: DxDataGridTypes.EditorPreparingEvent<Employee, number>) { if (e.dataField === 'LastName' && e.parentType === 'dataRow') { e.editorOptions.disabled = e.row?.data && e.row?.data.FirstName === ''; } } onButtonClick() { const keys: number[] = this.dataGrid.instance.getSelectedRowKeys(); } }
<dx-button text="Get Selected Keys" (onClick)="onButtonClick()" > </dx-button> <dx-data-grid ... (onEditorPreparing)="onEditorPreparing($event)" > </dx-data-grid>
Vue
<template> <div> <DxButton text="Disable DataGrid" @click="onButtonClick" /> <DxDataGrid :data-source="dataSource" ref="dataGridRef" @editor-preparing="onEditorPreparing" > </DxDataGrid> </div> </template> <script setup lang="ts"> import { ref } from "vue"; import { DxDataGrid } from "devextreme-vue/data-grid"; import { DxButton } from "devextreme-vue/button"; import { type DxDataGridTypes } from "devextreme-vue/data-grid"; import type dxDataGrid from 'devextreme/ui/data_grid'; import { type Employee } from '../data'; const dataGridRef = ref<DxDataGrid>(); function onButtonClick() { const dataGridInstance: dxDataGrid<Employee, number> = dataGridRef.value?.instance!; dataGridInstance.option("disabled", true); } function onEditorPreparing(e: DxDataGridTypes.EditorPreparingEvent<Employee, number>) { if (e.dataField === 'LastName' && e.parentType === 'dataRow') { e.editorOptions.disabled = e.row?.data?.FirstName === ''; } } </script>
React
import { useRef } from 'react'; import { type Employee, employees as dataSource } from './data'; import DataGrid, { type DataGridTypes, DataGridRef } from 'devextreme-react/data-grid'; import Button from 'devextreme-react/button'; function onEditorPreparing(e: DataGridTypes.EditorPreparingEvent<Employee, number>) { if (e.dataField === 'LastName' && e.parentType === 'dataRow') { e.editorOptions.disabled = e.row?.data && e.row?.data.FirstName === ''; } } function App() { const dataGrid = useRef<DataGridRef<Employee, number>>(null); const onButtonClick = () => { const dataGridInstance = dataGrid.current!.instance(); dataGridInstance.option("disabled", true); } return ( <> <Button text={"Disable DataGrid"} onClick={onButtonClick} /> <DataGrid<Employee, number> ref={dataGrid} onEditorPreparing={onEditorPreparing} dataSource={dataSource}> </DataGrid> </> ); } export default App;
Configuration Components
DevExtreme Angular allows you to configure UI component settings using configuration components. These start with the dxo
and dxi
prefixes. DevExtreme includes two types of configuration components:
- Named configuration components
Components such asdxo-data-grid-popup
are specific to their parent UI components. The name of the parent UI component is included after thedxo
ordxi
prefix. - Generic configuration components
You can use components such asdxo-popup
to configure any supported UI component.
We recommend using named configuration components that are specific to the UI component you need to configure. Named configuration components are strictly typed in TypeScript and contain only properties related to their top-level UI components.
<!-- Stepper item example --> <dx-stepper ... > <dxi-stepper-item icon="docfile" label="Upload Supporting Files" [optional]="true" ></dxi-stepper-item> </dx-stepper> <!-- CardView editing example --> <dx-card-view ... > <dxo-card-view-editing [allowAdding]="true" [allowDeleting]="true" [allowUpdating]="true" ></dxo-card-view-editing> </dx-card-view>
You can implement named configuration components for nested DevExtreme components, such as the editing Popup within the DataGrid. To do this, specify top-level component names. For instance, to configure Popup animation settings within a DataGrid, implement the <dxo-data-grid-animation>
configuration component:
<dx-data-grid ... > <dxo-editing mode="popup" /> <dxo-data-grid-popup> <dxo-data-grid-animation [show]="showOptions" [hide]="hideOptions" ></dxo-data-grid-animation> </dxo-data-grid-popup> </dx-data-grid>
Specify Popup and Popover toolbar items as <...-toolbar-item>
(both for nested and non-nested controls), and other component toolbar items as <...-item>
:
<!-- Toolbar item in a DataGrid editing Popup --> <dx-data-grid ... > <dxo-editing mode="popup" /> <dxo-data-grid-popup> <dxi-data-grid-toolbar-item widget="dxButton" location="after" [options]="buttonOptions" ></dxi-data-grid-toolbar-item> </dxo-data-grid-popup> </dx-data-grid> <!-- Toolbar item in a Scheduler --> <dx-scheduler ... > <dxo-scheduler-toolbar> <dxi-scheduler-item name="dateNavigator"></dxi-scheduler-item> </dxo-scheduler-toolbar> </dx-scheduler>
If you have technical questions, please create a support ticket in the DevExpress Support Center.