Декларативный подход
Contents
Декларативный подход#
Для программирования компонентов в декларативном подходе используется библиотека react.
Модель данных#
Для облегчения взаимодействие модель данных может быть декорированная, основой декорации служит класс gs-web-dtk/gsreact/model.ts/NDataModelAbst
.
Декоратор узла модели данных позволяющий подписываться на изменения в декларации отображения компонента. Модель данных может отображать данные через привязанный датасет.
Хуки#
Для того чтобы подписаться на перерисовку интерфейса при изменении узла модели существуют хуки:
useTree
Хук для привязки к изменениям атрибутов и дочерних элементам.useTreeAndChContext
Хук для привязки к изменениям модели и dataset.
Привязка dataset#
Привязка dataset позволяет модифицировать данные модели через механизм dataset.
Для привязки модели к dataset необходимо переопределить в модели узла функцию getDataSetName
Примеры#
Пример модели:
export class Cols extends rm.NDataModelAbst{
getColsBySpan(startIndex:number,colspan:number): Col[]{
var cols = []
var cs = colspan
if (cs==undefined){
cs = 1
}
for(let i = 0;i<cs;i++){
cols.push(this.getChildAs(Col,startIndex+i))
}
return cols
}
}
export class Col extends rm.NDataModelAbst{
getDataSetName(): string {
return "cols"
}
getWidth():number{
return this.getAttrValue("width")
}
setWidth(value:number){
this.setAttrValue("width",value)
}
}
Пример отображения по модели данных:
/**
* Декларация псевдо строки где будут расположены ячейки с линейками для столбцов.
*/
export const RowTag = React.memo((props:{cols:Cols}) =>{
const cols = props.cols.useTree()
//console.log(`RowTag, cols:${cols}`)
var rullersContent = []
rullersContent.push(<td key="dummy" className={styleStore.getStyle("td")}></td>)
for(let curColIndex=0;curColIndex<cols.getChildrenCount();curColIndex++){
const col = cols.getChildAs(Col,curColIndex)
rullersContent.push(
<td key={curColIndex} className={styleStore.getStyle("td")}>
<RulerTag col={col}/>
</td>)
}
return <tr key="col-rulers">{rullersContent}</tr>
})
Подключение компонента к Dom#
Для подключения компонента необходимо переопределить функции компонента attach
и detach
.
Пример:
export class SomeControl extends Control.ControlAbst{
root : ReactDOM.Root
attach(parent: HTMLElement) {
this.root = ReactDOM.createRoot(parent);
this.root.render(tagBuilder(this.controller));
}
detach() {
this.root.unmount()
}
}