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

Вы можете использовать библиотеку Webix при разработке на Angular (Angular 2+). Описание интеграции с более ранними версиями фреймворка вы найдете здесь.

С примерами интеграции можно ознакомиться в этом репозитории.

Как запустить демо приложение

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

npm install
npm run start

Начальные приготовления

Для начала работы с Webix и Angular вам не нужны специальные инструменты. Все что вам следует сделать, это:

a) подключить ресурсы Webix в index.html:

<script src="//cdn.webix.com/edge/webix.js"></script>
<link rel="stylesheet" href="//cdn.webix.com/edge/webix.css">

b) добавить типизации Webix в typings.json:

npm run typings install df~webix --save --global

Работа с Webix компонентами

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

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

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

Обработчик ngOnInit нужен для того, чтобы подогнать размеры компонента к размерам родительского контейнера. Если размеры вашего Webix компонента описаны в конфиге, то обработчик можно не описывать.

Обработчик ngOnDestroy очистит память после удаления компонента.

Как загрузить данные в Webix компонент

Виджеты Webix могут загружать данные напрямую из сервера.

Для загрузки данных вы также можете использовать атрибуты @Input или сервисы для работы с данными. Они работают по такому же принципу как и для обычных компонентов Angular. В обоих случаях, данные должны парситься через свойство data компонента. Вы можете передать ему как обычный объект с данными, так и промис объекта.

app/services/film.ts

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


app/components/datatable.ts

constructor(private films: FilmService, root: ElementRef) {
    this.ui = <webix.ui.datatable> webix.ui({
        container: 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;
  @Output() onRowSelect = new EventEmitter<Film>();
 
  constructor(private films: FilmService, root: ElementRef) {
    this.ui = <webix.ui.datatable> webix.ui({
        container: root.nativeElement,
            view: "datatable", autoConfig: true, data: this.films.getFilms(),
            on: {
              onAfterSelect: (id)=>this.onRowSelect.emit(this.ui.getItem(id))
            }
      })
  }
}

В примере выше мы регистрируем событие "onRowSelect" для компонента DataTable. Это событие будет срабатывать при каждом селекте/выборе ряда таблицы.

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

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

В этом примере, родительский компонент отслеживает событие onRowSelect и показывает выбранную запись таблицы.

Свойство @Output позволяет работать с любыми событиями компонента.

Как работать с лейаутами Webix

Есть два способа с помощью которых вы можете создавать лейауты Webix в Angular 2. Первый и более предпочтительный подход заключается в том, чтобы определить все лейаут-компоненты Webix в одном Angular компоненте:

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

При втором подходе вы можете определить лейаут напрямую, как часть свойства template компонента.

Этот способ может показаться вам более приемлемым, но он чреват непредсказуемыми последствиями. Дело в том, что лейауты Webix используют концепцию фиксированных размеров, которая не совместима с тем, как строит интерфейс сам фреймворк.

Таким образом, вы можете использовать лайауты Webix, но их поведение будет отличаться от обычных Angular компонентов. Стоит также учитывать, что вы не сможете использовать ngIf чтобы скрыть/показать часть лейаута.

Принимая во внимание вышесказанное, вы все же можете использовать лейауты Webix в шаблоне Angular.

Есть 3 лейаут компонента, которые доступны в директории app/components/layout.ts:

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

Теги rows и cols поддерживают следующие атрибуты: type, padding и margin (они очень похожи на свойства лейаута Webix).

У тега cell есть собственные атрибуты, а именно: width, height, minWidth, minHeight, maxWidth, maxHeight и gravity (они также похожи на свойства компонентов Webix для управления размерами).

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

Webix UI не поддерживает атрибут routerLink для навигации между компонентами. Чтобы перейти к другому компоненту, вам следует использовать событие onItemClick текущего компонента:

this.ui = <webix.ui.menu>webix.ui({
    container: 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.

Как работать с Angular CLI

Если вы создаете проект на Angular с помощью инструмента CLI, не забудьте добавить webix в src/tsconfig.app.json:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "module": "es2015",
    "baseUrl": "",
    "types": [ "webix" ]
}

Вы можете проверить ветку Angular CLI вышеупомянутого репозитория, в которой находится демо-приложение, созданное с помощью CLI.

Наверх