Декларативный подход#

Для программирования компонентов в декларативном подходе используется библиотека 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()
    }

}