Интеграция с Angular

Библиотека Webix совместима с фреймворком Angular (Angular 2+). Интеграция с более ранними версиями описана в этой статье.

Пример использования Webix с Angular доступен на GitHub. Узнать больше об импорте комплексных виджетов Webix в приложение Angular можно в этом репозитории.

Запуск демо

Клонируйте упомянутый выше репозиторий и выполните следующие команды:

npm install
npm run start

Подключение файлов

Файлы Webix подключаются через параметры scripts и styles в angular.json:

"styles": [
  "src/styles.css",
  "node_modules/webix/webix.css"
],
"scripts": [
  "node_modules/webix/webix.js"
]

При создании нового проекта с помощью Angular CLI, добавьте типизацию Webix в tsconfig.json:

"include": [
    "src/**/*.ts",
    "./node_modules/webix/types/webix.global.d.ts"
]

Компоненты на основе Webix

Чтобы создать view на основе Webix, используйте обычный Angular-компонент с вызовом webix.ui внутри.

import { Component, ElementRef, OnDestroy, OnInit, inject } from '@angular/core';
 
@Component({
    selector: 'webix-datatable',
    template:''
})
export class DataTableComponent implements OnDestroy, OnInit {
    private ui : webix.ui.datatable;
    private root = inject(ElementRef);
 
    constructor(){
        this.ui = <webix.ui.datatable> webix.ui({
            container: this.root.nativeElement
            view:"datatable", autoConfig:true, url:"data.php"
        })
    }
 
    ngOnInit(){
      this.ui.resize();
    }
    ngOnDestroy(){
      this.ui.destructor();
    }
}

Вызов webix.ui в конструкторе класса инициализирует Webix view. Здесь можно использовать любой компонент Webix и любые параметры. Один Angular-компонент может содержать как один компонент Webix, так и лейаут с несколькими компонентами.

Обработчик ngOnInit подстраивает размер компонента под родительский контейнер (не обязателен, если в конфиге webix.ui заданы фиксированные размеры).

Обработчик ngOnDestroy очищает память при разрушении view.

Загрузка данных в компонент Webix

Компонент Webix может загружать данные напрямую с сервера, без инфраструктуры провайдеров данных.

При необходимости, можно использовать функцию input Angular или сервисы данных, так же, как для обычных Angular-компонентов. В обоих случаях данные передаются через свойство "data" компонента. Этот способ поддерживает как объекты данных, так и Promise с объектами данных.

app/services/film.ts

@Injectable()
export class FilmService {
    getFilms(): Promise<Film[]>{
        return Promise.resolve(FILMS);
    }
}


app/components/datatable.ts

private root = inject(ElementRef);
private films = inject(FilmService);
constructor(){
    this.ui = <webix.ui.datatable> webix.ui({
        container: this.root.nativeElement,
        view:"datatable", autoConfig:true, data: this.films.getFilms()
    })
}

Вызов API компонентов Webix

Добавьте публичный метод в компонент и используйте this.ui как ссылку на объект Webix:

app/components/datatable.js

addRow(){
    this.ui.add({ title:"New row" });
}

Обработка событий Webix

События компонента Webix можно использовать через свойство output:

app/components/datatable.js

export class DataTableComponent implements OnDestroy, OnInit {
  private ui : webix.ui.datatable;
  private root = inject(ElementRef);
  private films = inject(FilmService);
  readonly rowSelect = output<Film>();
 
  constructor(){
    this.ui = <webix.ui.datatable> webix.ui({
      container: this.root.nativeElement,
      view:"datatable", autoConfig:true, data: this.films.getFilms(),
      on:{
       onAfterSelect: (selection) => this.rowSelect.emit(this.ui.getItem(selection.id))
      }
    })
  }
}

Код выше регистрирует публичное событие "rowSelect" для компонента DataTable. Событие срабатывает при каждом выборе строки в компоненте Webix.

В родительском компоненте это событие можно обработать следующим образом:

@Component({
 selector: 'webix-html-layout',
 template: `<h2>Initializing Webix component in separate HTML containers</h2>
     <webix-datatable (rowSelect)="fillInfo($event)" class='pagebox'></webix-datatable>
     <div *ngIf="selectedFilm">
        <h3> Selected Film </h3>
        <ul>
           <li> Title : Film.title </li>
           <li> Votes : Film.votes </li>
        </ul>
     </div>
     `
})
export class HTMLLayoutComponent {
    selectedFilm: Film;
    fillInfo(film: Film){
      this.selectedFilm = film;
    }
}

Родительский компонент подписывается на событие rowSelect и отображает информацию о выбранной записи.

Аналогичный подход применим для любых других событий через свойства output.

Лейауты Webix

Есть два способа использовать лейауты Webix вместе с Angular. Рекомендуемый подход: разместить все компоненты на основе лейаута Webix в одном Angular-компоненте:

export class MyLayoutComponent implements OnDestroy, OnInit {
  private ui : webix.ui.datatable;
  private root = inject(ElementRef);
  private films = inject(FilmService);
 
  constructor(){
    this.ui = <webix.ui.layout> webix.ui({
        container: this.root.nativeElement,
        view:"layout",
        rows:[
            some,
            other,
            { cols:[ views, here ] }
        ]
    })
  }
}

Второй подход предполагает определение лейаутов непосредственно в свойстве template. Это заманчивый вариант, однако он может вызывать проблемы: лейауты Webix основаны на концепции фиксированных размеров, которая несовместима с подходом Angular к построению UI. Лейауты Webix будут работать иначе, чем обычные Angular-компоненты. В частности, невозможно использовать директиву ngIf, чтобы скрывать или показывать части лейаута.

Тем не менее, лейауты Webix можно использовать из шаблона Angular. В директории app/components/layout.ts предоставляется три компонента лейаута:

  • webix-columns — создаёт лейаут из столбцов
  • webix-rows — создаёт лейаут из строк
  • webix-cell — оборачивает отдельную ячейку лейаута
<webix-rows type="space" class="pagebox">
  <webix-cell>
    <webix-toolbar (buttonClick)="handleButtonClick($event)"></webix-toolbar>
  </webix-cell>
  <webix-cell>
    <webix-columns type="wide">
      <webix-cell width="300"><webix-sidebar></webix-sidebar></webix-cell>
      <webix-cell><webix-datatable></webix-datatable></webix-cell>
    </webix-columns>
  </webix-cell>
</webix-rows>

Теги webix-columns и webix-rows поддерживают атрибуты type, padding и margin (аналогично лейаутам Webix).

Тег webix-cell поддерживает атрибуты width, height, minWidth, minHeight, maxWidth, maxHeight и gravity, аналогично атрибутам размеров в Webix.

Маршрутизация

Атрибуты routerLink нельзя задать внутри Webix UI. Для перехода к другому view используйте событие onItemClick компонента:

this.ui = <webix.ui.menu>webix.ui({
    container: this.root.nativeElement,
    view: "menu", layout: "y", minHeight: 200, select: true,
    data: [
        { id: "html-layout", value: "HTML Layout" },
        { id: "webix-layout", value: "Webix Layout" },
        { id: "form-grid", value: "Form and Grid" }
    ],
    on: {
        onItemClick: (id) => this.router.navigate([id])
    }
})

Ограничения

Лейауты Webix несовместимы с ngIf и другими директивами, изменяющими DOM.

Наверх