Привязка данных определяет выбранный элемент компонента как источник данных для другого. Например, форму часто привязывают к какому-либо компоненту данных:
$$("myform").bind($$("list"));
// ...
$$("myform").save();
Далее мы рассмотрим другие примеры, а также тонкости использования привязки данных.
Курсор используется для определения активного элемента данных. Курсор хранит ID элемента данных, выбранного в текущий момент в компоненте-мастере.
Когда в компоненте данных выбран какой-либо элемент, компонент отмечает его курсором. Поскольку в коллекции данных выбирать элементы нельзя, вам необходимо сделать это самостоятельно. Для этого и предназначен курсор в DataCollection.
Курсор необхоим в ситуациях, когда несколько компонентов привязаны/синхронизированны с одним источником данных, например коллекцией данных. Он нужен для того, чтобы избежать конфликтов между компонентами, которые ссылаются на один и тот же источник данных и изменяют его.
Вы можете получить/задать курсор с помощью следующих методов:
var cursor = master.getCursor();
Чтобы удалить текущую привязку, задайте null в качестве параметра метода setCursor:
master.setCursor(null);
Если форма (зависимый компонент) привязана к списку (мастеру), а курсор снят со списка, то форма очистится.
Курсор может быть полезен при работе с DataCollections.
Когда вы привязываете компоненты, зависимый компонент получает 3 события:
$$("files").bind($$("folders"));
$$("files").attachEvent("onBindApply", function(){
// очищает превью темплейт
$$("preview").setHTML("");
});
Это касается только тех компонентов, у которых есть свойство template. В form и htmlform привязка осуществляется согласно их свойству name.
Если в мастере нет выбранных компонентов, зависимый компонент покажет значения undefined. Для такой ситуации вы можете задать значения по умолчанию. Используйте свойство мастера - defaultData:
webix.ui({
rows:[
{
view:"list",
template:"#rank#.#title#",
// data: ...
defaultData:{
rank:"0",
title:"default Item"
}
},
{ view:"template", template:"#rank#.#title#" }
]
})
$$("template1").bind($$("list1"));
Более подробно о CollectionBind API.
Когда форма привязана к компоненту, данные выбранного элемента приходят в форму. Любые изменения в форме автоматически отображаются в выбранном элементе. Это происходит при вызове метода save():
$$("myform").save();
Если при вызове метода форма будет пустой, то в мастер добавится новый элемент.
Вы также можете сохранять дополнительные данные вместе со значениями формы. Для этого получите значения формы, добавьте необходимые свойства и передайте полученный объект в метод form.save():
var values = form.getValues();
values.myfield = "My value";
form.save(values);
Если к компоненту привязаны 2 формы и вы сохраняете каждую из форм по отдельности, данные из первой сохранённой формы исчезнут.
Существуют два возможных решения:
1) Получить данные обеих форм и объединить их с помощью extend:
var v1 = $$("form1").getValues();
var v2 = $$("form2").getDirtyValues();
$$("form1").save( webix.extend(v1, v2, true) ); // комбинирует данные двух форм
2) Использовать метод saveBatch который сохраняет данные нескольких форм, вместе с методом getDirtyValues, который блокирует переопределение данных
$$("datatable1").saveBatch(function(){
$$("form1").save();
$$("form2").save( $$("form2").getDirtyValues() );
});
Метод getDirtyValues возвращает только те поля, которые были изменены.
Кастомизация возможна только если у зависимого компонента есть DataStore или TreeStore (DataTable, Tree, List, Chart, и т.д.).
Вы можете изменить шаблон привязки по умолчанию, согласно которому записи в зависимом компоненте фильтруются с помощью rules. Вы можете определить rule как функцию или строку и передать её в метод bind() вторым параметром.
В виде функции, правило принимает 2 параметра:
Давайте привяжем список к richselect и установим правило: данные списка фильтруются в зависимости от выбранной опции в richselect:
Зависимый список отображает элементы категории равной значению в мастере
$$("list").bind($$("richselect"), function(slave, master){
return slave.category == master;
});
Related sample: List Data Bound to Richselect
Вы также можете использовать правило-функцию, чтобы заблокировать привязку динамически. Давайте привяжем две таблицы и если в мастере не будет выбранных элементов - заблокируем ёё:
Зависимая таблица показывает, записи равные записям в мастере
gridb.bind(grida, function(slave, master){
if (!master) return false; // блокируем привязку
return master.id == slave.movie;
});
Related sample: Linking Tables
Обратите внимание, задавать значение для компонента-мастера нужно после загрузки данных.
Правило-строка приходится кстати, когда вы привязываете компонент к иерархическим данным (Tree, TreeTable). Правило поможет решить, какие уровни данных передавать в зависимый компонент. Правило может включать следующие флаги:
Давайте привяжем таблицу к дереву и добавим дочерние элементы выбранного в таблицу:
$$("grid").bind( $$("tree"), "$level");
// иерархические данные выбранного узла
{ id:"3", value:"Node 3", data:[
// будут показаны в зависимом компоненте
{ id:"3.1", value:"Subnode 3.1" },
{ id:"3.2", value:"Subnode 3.1" }
]}
Related sample: Tree Data Binding
Эта особенность также полезна при привязке к иерархическим данным. По умолчанию, дочерние элементы представлены свойством data во всех поддерживаемых форматах данных. Если вы хотите добавить данные под другим ключём (например "records"), передайте имя ключа как формат строки. format передаётся в качестве третьего параметра в метод bind().
Давайте привяжем таблицу к иерархическим данным и воспользуемся правилом $data вместе с форматом records:
$$("grid1").bind( $$("tree"), "$data", "records");
// иерархические данные выбранного узла
{ id:"3", value:"Node 3", records:[
// будут показаны в зависимом компоненте
{ id:"3.1", value:"Subnode 3.1" },
{ id:"3.2", value:"Subnode 3.1" }
]}
Related sample: Tree Data Binding: Subdata
Формат можно задать в виде функции и описать в ней логику привязки вручную. Например, давайте зададим функцию, которая будет добавлять data и records из выбранного узла:
$$("grid2").bind( $$("tree"), "$data", function(obj, source){
if (!obj) return this.clearAll();
var fulldata = [].concat(source.data.getBranch(obj.id)).concat(obj.records);
this.data.importData(fulldata, true);
});
Мы получили дочерние элементы узла с помощью метода getBranch(). Затем скомбинировали их с данными по ключу records и импортировали полученный массив в зависимую таблицу.
Related sample: Tree Data Binding: Subdata
Как правило, зависимый компонент не общается с сервером напрямую. Он получает данные из своего мастера. Изменённые же данные сначала отправляются в мастер, который передаёт их на сервер.
Однако вы можете получить серверные данные для зависимого компонента с помощью dataFeed.
webix.ui({
view:"form",
id:"myform",
// ...конфиг
dataFeed: "slave_data.php"
});
$$("myform").bind($$("mydatatable"));
Свойство задаёт URL, которым воспользуется зависимый компонент и отправит запрос на сервер в момент смены выбранного элемента в мастере.
Это также работает для форм и коллекций (компонентов данных), но параметры URL отличаются:
где obj выбранный объект даннык в мастере.
Наверх