Развитие клиентской объектной модели веб-доступа

13 6

Когда появилась клиентская объектная модель, мы составили ряд работ по ее дальнейшему развитию. Были проанализированы пожелания от клиентов, рассмотрены типовые сценарии использования объектной модели. Круг заинтересованных лиц возрастал, опытные разработчики и те, кто уже успел поработать с клиентской объектной моделью, делились с нами своими идеями, которые мы также постарались реализовать в новой версии 5.1.

В настоящее время существенно дополнился исходный список объектов и классов, позволяющих, например, создавать пользовательские диалоги с реквизитами, удобно работать с карточками документов и справочников. Также были пересмотрены ранее созданные объекты: некоторые из них доработаны, а часть оставлена для совместимости. Об этом расскажу подробнее, по порядку.

Уход от CardForm

CardForm появился задолго до появления клиентской объектной модели и существовал просто как некий глобальный объект. Для тех, кто не сталкивался с разработкой веб-модулей, поясню, что такое CardForm.

CardForm – это JavaScript-объект, который имеет методы для работы с реквизитами карточки. Если программист написал вычисление на ISBL, срабатывающее на определенных реквизитах карточки, то в веб-доступе в некоторых случаях вычисление работать не будет. Причины заключаются в особенностях работы веб-доступа – в том, как он эти события интерпретирует. То есть, чтобы в веб-доступе заставить один реквизит мгновенно отреагировать на внешние факторы или, например, на смену другого реквизита, потребуется написать JavaScript-код. Другими словами, ISBL-код в браузере исполнить невозможно.

CardForm справлялся с данными задачами, но принципы, по которым он работал, сильно отличались от механизма, по которому работают все объекты клиенткой объектной модели, поэтому в чистом виде взять и перенести мы его не могли. Мы отошли от него и объявили устаревшим. Тем не менее он оставлен для обратной совместимости и автоматически подгружается, но только тогда, когда кто-то к нему обращается.

Итак, что же изменилось? На самом деле тут все просто, особенно для тех, кто уже работал с CardForm и знаком с клиентской объектной моделью (а такие люди есть, я сам видел!).

В существующем пространстве имен WebAccess.current.form появляется дочернее requisites, которое уже имеет доступ к реквизитам формы. Сам WebAccess.current.form также расширяется, у него появляются новые методы, например, WebAccess.current.form.save() – сохранит карточку текущего открытого документа или записи справочника.

Кстати, CardForm не мог изменять реквизиты, не вынесенные на карточку, а WebAccess.current.form – может!

К примеру, мне нужно, чтобы мой реквизит Пользователь становился доступным для изменения, когда в реквизит Дата введено какое-то значение и наоборот.

Для этого в созданном веб-модуле добавим строки:

WebAccess.current.form.requisites["Дата"].bind('change', function(element, event, data) {
  if (data.value) {
    WebAccess.current.form.requisites["Пользователь"].enable();
  } else {
    WebAccess.current.form.requisites["Пользователь"].disable();
  } 
});

В результате сразу после выбора даты поле для выбора пользователя станет доступным:

Если в поле Дата пересмотра удалить значение, то поле Пересмотрел вновь станет недоступным.

Приведенный код можно немного улучшить, сократив слегка отпугивающие длинные цепочки:

var requisites = WA.CR.form.requisites;
var dateReq = requisites['Дата5'];
var userReq = requisites['Пользователь6'];
dateReq.bind('change', function(element, event, data) {
  if (data.value) {
    userReq.enable();
  } else {
    userReq.disable();
  }
});

Пример будет работать будет точно так же, как первый.

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

userReq.setValue(WA.CR.user.ID, WA.CR.user.fullName);

Наверное, у кого-то возникнет вопрос, почему в некоторых примерах пишем WebAccess, а в каких-то WA, где-то WebAccess.current, а где-то WA.CR? На самом деле нет никакой разницы – это все ссылки на один и тот же объект. Как писать – решать вам. Подобные сокращения мы сделали исключительно для удобства.

Кстати,  заполнение и работа с таблицами на карточках объектов тоже должна стать проще. Работа с таблицами карточек объектов значительно улучшена и доработана.

Как и раньше детальный раздел можно скрыть (метод hide), таблицу на карточке можно показать (метод show) или сделать недоступной для изменения (метод disable) и не только. Все это можно применить и к строкам, и к столбцам, и к реквизитам.

Но самое главное, что объекты WA.CR.form.controls.tables и WA.CR.details доработаны аналогично WA.CR.form, и используют такие-же классы для работы с реквизитами. Стало возможно обращаться к реквизитам строки таким же образом, как мы обращаемся к реквизитам карточки, и обрабатывать аналогичные события. Теперь стало проще добавлять новые записи в таблицу, причем можно добавлять запись с изначально заполненными реквизитами.

Классы WebAccess.Link и WebAccess.URL

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

WebAccess.URL (сокращенно WA.URL). Класс пришел на замену глобальных функций GetParamInURL, SetParamInURL и прочих, никому кроме самого веб-доступа, неизвестных функций. Как можно догадаться, WA.URL – это класс для работы с URL-адресами. Покажем возможности данного класса на примерах.

Откроем страницу Яндекса с результатами поиска по фразе 'DIRECTUM – что это?':

var url = new WA.URL('http://yandex.ru/yandsearch');
url.setParam('text', 'DIRECTUM – что это?');
url.open();

Если нужно получить и обработать URL текущей страницы, достаточно создать экземпляр этого класса, не передавая параметры в конструктор. Посмотрим следующий пример.

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

var url = new WA.URL();
url.setParam('refview', 'main');
url.open();

URL совсем не обязательно открывать, его можно вернуть в виде строки, которую потом уже использовать для своих нужд, для этого можно воспользоваться методом asString;

Класс WA.Link – это ссылка на объект системы. Как и в случае с URL, если вызвать ссылку без параметров, она будет ссылаться на текущий открытый объект.

Например, попробуем вызвать ссылку без параметров в задаче:

var link = new WA.Link();

В результате получим ссылку, которая хранит ИД и тип объекта:

console.log(link.asString());
// "{"id":3346287,"type":2,"referenceName":null}"

Классы WA.Link и WA.URL связаны друг с другом. Из экземпляра класса WA.Link можно получить экземпляр класса WA.URL, используя метод toURL. После получения экземпляра будет доступна работа со ссылкой, которая может открыть объект на странице веб-доступа. Порой, это очень удобно.

К примеру, откроем задачу с ИД = 3346287 на закладке «История»:

var link = new WA.Link(3346287, OBJECT_TYPE.TASK);
var url = link.toURL();
url.setParam('view','History');
url.open();

Так подробно про ссылки я рассказал потому, что такие ссылки часто будут встречаться при работе с фабриками. А о них я расскажу далее.

Фабрики

Впервые фабрики появились в объектной модели IS-Builder и в серверной объектной модели веб-доступа. Они были созданы для удобной работы с объектами системы DIRECTUM. Теперь фабрики есть и в клиентской объектной модели. Их функционал сейчас скромный, по большому счету их можно использовать лишь для создания объектов. Тем не менее, это тоже большой шаг вперед.

Поскольку природа фабрик такова, что все они работают через сервисы веб-доступа, то это накладывает свои особенности на работу с ними. Фабрики основаны на deferred-объектах. Что такое deferred (а также promise), можно почитать в интернете, а я лучше покажу на примерах.

Создадим новую задачу и откроем ее карточку:

WebAccess.factories.tasks.createTask().done(function(task) {
  //здесь task - это экземпляр уже знакомого нам класса WebAccess.Link
  task.open();
});

Как правило, если требуется создать объект, то необходимо заполнить его параметры. После создания не всегда нужно открывать объект, достаточно просто сохранить его или, как в случае с задачами – запустить.

Теперь создадим задание, заполним его параметры, сохраним и автоматически запустим, попутно открыв его карточку:

var taskSettings = {
  subject: 'Задача, созданная фабрикой',
  activeText: 'Текст задачи',
  parent: new WA.Link(65, OBJECT_TYPE.JOB),
  attachments: [new WA.Link(65, OBJECT_TYPE.JOB)],
  route: [133311,132970],
  observers: [133311],
  autoSave: true,
  autoStart: true
};

WA.FC.tasks.createTask(taskSettings).done(function (task){
  task.open()
});

В результате откроется карточка задачи:

Все возможные параметры можно найти в справке, и этот пример тоже.

Вообще в текущей версии справки мы старались делать упор на примеры, так как обычно, именно примеры лучше всего показывают полную картину описанного в справке.

Обновления FormBuilder

С данным классом вы могли познакомится в предыдущей версии 5.0. Основная цель этого класса – строить формы. В версии 5.1 он был значительно переработан, а также получил новый набор реквизитов, например, objectList. Использование данного реквизита можно встретить в веб-доступе, в мастерах действий: разработка флажков и переключатели, полей для выбора файлов и многие другие.

А еще класс получил новые правила проверки на корректность заполнения полей, а также возможность создавать свои правила:

Глобальные функции

Вдобавок, в этой версии (впрочем, как и в прошлой) постарались максимально учесть нужды разработчика, и нашли много полезных функции, которые ранее были разрознены по разным частям веб-доступа. Мы постарались собрать их и сгруппировать, но, так как они достаточно разнородные, не со всеми это получилось сделать и такие уникальные функции мы оставили глобальными.
Глобальные функции являются неотъемлемой частью клиентской ОМ и всегда будут рядом с ней в следующих версиях. Таких функций немного, и необязательно знать их в лицо, достаточно посмотреть их описание с готовыми примерами в справке DIRECTUM.

В заключение

На самом деле осталось еще множество новшеств и доработок, которые просто не поместить в одну статью. Например, теперь шаблоны разработки веб-модулей, упрощающие разработку в целом, включены в стандартную поставку. Использование шаблонов позволит также работать со встроенными подсказками к объектам – IntelliSense.

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

Андрей Михайлов

Это хороший и интересный материал. Но... В первую очередь не хватает информации о базовых вещах, нужен пример на пальцах разъясняющий как создать web-модуль, как писать и подключать javascript файлы и т.д. с нуля. А то что есть в справке никак не раскрывает эту тему.

Павел Евдокимов

Отличный материал! Спасибо!

По поводу комментария Андрея Михайлова, есть такой материал. Автор статьи Андрей Широбоков. Будет не лишним добавить ссылку на этот материал сюда. 

Андрей Михайлов

Павел по ссылке ругается на отсутствие прав доступа. Это секретные материалы?

Павел Евдокимов

Странно... 

http://club.directum.ru/post/Materialy-s-master-klassa-po-razrabotke-veb-modulejj.aspx

А вот так?

Андрей Михайлов

Ссылка то осталась такой же как и в предыдущем посте, ну и результат тот же: Forbidden | У вас нет доступа.

Елена Питомцева

Андрей Михайлов доступ к материалам http://club.directum.ru/post/Materialy-s-master-klassa-po-razrabotke-veb-modulejj.aspx теперь открыт для всех пользователей с расширенным доступом (он у вас есть).

Авторизуйтесь, чтобы написать комментарий