Intermediate

Привязка и синхронизация данных

Если у вас на странице есть несколько компонентов с одним источником данных, вы можете соединить их. Это значит, что изменения в одном компоненте вызовут изменения в других. Существует 3 способа, как это можно сделать:

  • привязка
  • синхронизация
  • импорт

Все 3 способа подразумевает, что есть компонент-мастер и зависимые компоненты. Мастер служит источником данных для зависимых компонентов.

Разница между синхронизацией и привязкой

Когда вы привязываете один компонент к другому, то при выборе элемента в одном из компонентов, этот элемент становится источником данных для другого компонента. В большинстве случаев, привязка используется, когда есть какой-либо компонент данных (мастер) и form / htmlform (зависимый).

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

Привязка данных

Как этим пользоваться

Чтобы привязать компоненты, вызовите метод bind() на зависимом компоненте и передайте в него компонент-мастер в качестве параметра.

$$("form1").bind($$("list1"));

Если вы выберете элемент в списке, форма заполнится данными этого элемента.

Обратите внимание, что свойство полей формы name должно совпадать с именами полей с данными компонента.

// данные компонента
{ name:"Jane", age:23 }
// форма
{
    view:"form", elements:[
        { name:"name", view:"text" },
        { name:"age", view:"text", type:"number" }
    ]
}

Изменения в зависимом компоненте влияют на компонент-мастер. Если вы отредактируете данные в форме и затем сохраните их, элемент с списке тоже обновится. Чтобы сохранить изменения, вызовите на форме метод save(). Обратите внимание, что метод save() можно вызвать только на тех формах, у которых есть мастер.

$$("form1").save();

Зависимый компонент можно отвязать от мастера с помощью метода unbind():

$$("form1").unbind();

Related sample:  Creating Basic App: Step 3

Related sample:  Binding to a Native HTML Form

Как это работает

Здесь нет никакой магии. Это синтаксический сахар для более прямолинейного подхода привязки путём событий. Например, того же результата можно достичь с помощью следующих API:

// выбираем элемент с писке и заполняем форму
$$("list1").attachEvent("onAfterSelect", function(id){
    var item = this.getItem(id);
    $$("form1").setValues(item);
});
 
// сохраняем данные формы в список
view:"form", id:"form1", elements:[
    // ...
    {
        view:"button", value:"Save", click:function(){
            var item = this.getFormView().getValues();
            $$("list").updateItem(item.id, item);
        }
    }
]

Такой вариант подойдёт, если вы используете Webix Jet, т.к. форма и её мастер весьма вероятно находятся в разных файлах и привязка с помощью первого варианта невозможна.

Расширенный вариант привязки

У привязки данных также есть расширенные опции:

  • дополнительные параметры для кастомизации;
  • привязка иерархических структур;
  • система событий;
  • нативное API для указания исходного источника данных (если в мастере не выбраны никакие элементы);
  • привязка к коллекции данных.

Изучите эту статью для более глубокого понимания темы.

Синхронизация компонентов

Синхронизация данных позволяет копировать данные из одного компонента в другой. Любые изменения, вызванные в компоненте-мастере спровоцируют те же изменения в зависимом компоненте. Если изменения происходят в зависимом компоненте, то только обновления отразятся в мастере. Читайте подробнее об операциях с данными

Зависимых компонентов может быть несколько. В этом случае все они будут изменяться при изменениях в их мастере.

Вот так можно синхронизировать компоненты:

$$("зависимый_компонент").sync("компонент_мастер");

Синхронизация с коллбэком

Вы можете задать определённое поведение для зависимого компонента. Например, можно отфильтровать элементы, сгруппировать данные и т.д. перед тем, как они отобразятся в зависимом компоненте. Для этого передайте коллбэк вторым параметром в метод sync()

Фильтрация

Например, вот так вы сможете отфильтровать данные в коллбэке. Показаны только те фильмы, которые были сняты после 1994 года:

$$("dview2").sync($$("listA"), function(){
    this.filter(function(data){
        return data.year > 1994;
    });
});

Больше информации о фильтрации.

Группировка

Вы можете сгруппировать данные перед тем, как они отобразяться в зависимом компоненте. Например:

$$("chart").sync($$("customers_grid"), function(){
    this.group({
        by:"status",
        map:{
            value:["value","count"]
        }
    });
});

Больше информации о группировке.

Как убрать синхронизацию

Вызовите метод unsync у зависимого компонента, чтобы убрать синхронизацию:

$$("dview2").unsync();

Операции с данными

Когда компоненты синхронизированны, любые операции с данными в мастере отражаются в зависимом компоненте. Мастер задаёт данные для всех зависимых от него компонентов. Последние могут лишь обновлять элементы данных в мастере. Поэтому вам следует:

  • обновлять данные в зависимом компоненте или мастере
$$("slave").updateItem("itemId", { new_data:"some data" });
// или
$$("master").updateItem("itemId", { new_data:"some data" });
  • добавлять и удалять элементы только в мастере
$$("master").add({ new_data:"some data" });
$$("master").remove("itemId");

Заметки дял пользователей Webix Jet

Если вы разрабатываете на Webix Jet, синхронизация визуальных компонентов невозможна по причине того, что компоненты в большинстве случаев находятся в разных модулях, а UI отделён от логики загрузки/сохранения данных. Самый проверенный способ для Jet, это создать модель данных с коллекцией данных и импортировать её в компоненты.

Импорт данных

Импорт данных позволяет синхронизировать данные двух компонентов (один из них может быть коллекцией данных) без дальнейшего прослушивания изменений.

Зависимый компонент получит данные мастера через метод importData:

$$("listB").data.importData($$("listA"));

Обратите внимание, что это модуль DataStore, и поэтому его нужно вызывать для данных (data) компонента.

Держите в уме, что метод importData method не копирует данные, так что элемент обновится в обоих виджетах после обновления компонента.

Вот так можно полностью скопировать данные из одного компонента в другой:

$$("listB").parse($$("listA").serialize());
Наверх