Утилита для кодинга - Фабрика компонентов

Javascript, jComponent, Node.js, Total.js 18 июня 2020 2 мин. 413


Всем привет! Прежде чем выложить этот пост, я долго думал стоит ли это делать. Просто терзали некоторые сомнения - "Не будет ли моя поделка выглядеть смешно на фоне других проектов?!". Как и многие разработчики я пишу свои "велосипеды" - утилиты, потом появляются мысли, а если это нужно мне, может ещё кому то пригодится. Поэтому хочется рассказать, что меня с подвигло на это, как писал и как это работает.


Общий вид утилиты, редактор html и результат
Общий вид утилиты, редактор html и результат

Предыстория

Год назад я участвовал в проекте, проект был связан со сбором статистики. И там много было разных форм и табличек, и через какое то время эти формы и таблички могли меняться в соответствии с новыми требованиями. И я предложил вариант, когда заказчик сам может дорабатывать свой проект не обращаясь или просто консультируясь со мной удаленно. Поэтому я решил сделать некий аналог codepen, но для внутреннего использования, который бы был интегрирован с API бэкенда. Проект успешно внедрен и работает в одной государственной структуре, уже на протяжении 1 года. Я подумал, поскольку все успешно работает, значит моя утилита может быть использована не только мною и она заслуживает хоть какого то внимания.


Как разрабатывал

Времени на разработку ушло пару дней. Поскольку основной проект писался с использование фреймворка total.js, в бэкенде был использован именно он. Фронтенд писался с использованием моих компонент, а также компонент с сайта componentator.com. Но в моей утилите можно использовать любые jquery плагины, главное, чтобы в сборке были подключены эти ресурсы и скрипты. Так как утилита, берет все ресурсы с бэкенда.


Идея

Основную идею я почерпнул у онлайн сервиса codepen. Мне нравилось, когда что то пишешь и сразу видишь результат, но мне не нравилось, что нельзя пользоваться собственным внутренним API, а также нельзя использовать формы в своём проекте. Поэтому решил сделать следующим образом отдельный редактор html кода, и редактор javascript. Для css не стал ничего делать, так как основные стили и так уже идут к проекту и смысл делать отдельного редактора я не увидел. Также сделал раздел params это настройки формы, а также отдельная настройка path-to-object, мне показалось это удобным особенно для новичков (которые не в курсе, что такое databinding), сразу можно посмотреть как у тебя формируется нужный объект, как заносятся данные, а результат можно посмотреть на вкладке object. Также был сделал сам viewer, где отображается сам результат. Формы, таблички и другие элементы интерфейса сохраняются в БД (по умолчанию noSQL, также есть поддержка БД postgreesql, mysql, mongodb) и в любой момент можно будет их отредактировать. Кроме этого любой элемент можно будет вызвать в основном проекте, для этого я написал небольшой компонент jc-fabric. Компонент обращается к бэкенду и загружает из базы компонент и запускает его. Все вызовы компонентов я кэширую в localstorage браузера. Все идеи, которые у меня были я реализовал. Позже появились мысли, может сделать как в Delphi, выбираешь компонент, кидаешь его настраиваешь. Но мне показалось это слишком трудоёмким и не очень универсальным. Может у Вас будут какие то идеи?

Редактор
Редактор
Наблюдаемый JSON объект
Наблюдаемый JSON объект
Параметры формы
Параметры формы

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

Для начала скачаем исходники https://github.com/saper639/fabric. Затем нужно установить total.js.

npm install total.js

Запустим сервис командой:

node debug.js

После чего, открываем браузер по адресу http://localhost:2229. И можно приступать к работе. Сперва можно посмотреть пару примеров, которые я сделал введя "example..." в поле Enter form name, выбрать нужную форму и поэкспериментировать. Затем можно что то создать самому, кликаем по меню New, заполним некоторые параметры на вкладке Params, а именно:

  • Slug - название (латиницей), именно по этому имени мы и будем впоследствии вызывать компоненты
  • Name - более расширенное название
  • Path to object - имя объекта, которое необходимо отображать во вкладке Object. В моих нескольких примерах, можно понять как это работает

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

Используем с другим проектом

Конечно, желательно использовать UI фреймворк jcomponent. С другими фреймворками я не тестировал, но я думаю, что редактор и вьювер должны работать без проблем. Только разве что, не получиться использовать эти формы в своём проекте, ну или что то придётся доработать. У вашего проекта и данного сервиса/утилиты, общее будет только база данных, табличка fabric. В корне исходников лежит файл fabric.sql со структурой таблицы fabric. И Вашем проекте нужно как то просто извлекать, сохранённые формы из БД.

Как использовать c другими базами данных

Я постарался реализовать минимальную поддержку для работы с другими базами данных типа mysql, postgreesql, mongodb. Если вы используете другую, то придется немного дописать, но это не очень сложно.

Сперва необходимо установить дополнительные компоненты к моему сервису. Это нативная библиотека для работы с БД, а также универсальная ORM sqlagent. Ставим нативную библиотеку для нужной БД.

  • MySql npm install mysql
  • PostgreeSql npm install pg
  • Mongodb npm install mongodb

Затем устанавливаем ORM для работы с этими базами:

npm install sqlagent

После чего в файл config необходимо добавить параметры настроек в зависимости от используемой БД. Пример:

  • mysql://user:password@127.0.0.1:port/database
  • postgresql://user:password@127.0.0.1:port/database
  • mongodb://user:password@127.0.0.1/database

После чего добавим в Вашу БД табличку fabric из файла fabric.sql.

Как использовать формы в своём проекте

Это очень просто. Для этого я написал небольшой компонент jc-fabric. Использует библиотеку jcomponent. Вот его код:

COMPONENT('fabric', function(self, config) {
    var meta = {};
    self.make = function() {                
        if (config.url) {
            AJAX('GET '+config.url, null, (resp, err)=>{                              
                self.append(resp.html);
                self.append('<script>'+resp.code+'</script>');                                
                meta.id = resp.id;                 
                meta.name = resp.name;                 
                meta.param = resp.param;                 
            });
        }    
    }    
});    

В этой версии при вызове компоненты, они не кэшируются, иногда нужно для разработки и отлаживания. Чтобы использовать кэширование, нужно немного переписать компонент:

COMPONENT('fabric', function(self, config) {
    var meta = {};
    self.make = function() {                
        if (config.url) {
            AJAXCACHE('GET '+config.url, null, (resp)=>{                              
                self.append(resp.html);
                self.append('<script>'+resp.code+'</script>');                                
                meta.id = resp.id;                 
                meta.name = resp.name;                 
                meta.param = resp.param;                 
            }, '5 days');
        }    
    }    
});    

Чтобы вызвать, нужную нам форму, таблицу или другой элемент UI, необходимо в html разместить следующее код:

<div data-jc="fabric__null__url:/fabric/example_form1"></div>    

В параметре url содержится путь к бэкенду, после чего бэкенд вернет содержимое формы и нужный javascript.

Рекомендации по разработке

При использовании своей утилиты, я столкнулся с некоторыми проблемками - это переменные. Да в Вашем проекте, тоже такое может быть, конфликты переменных. Но самая проблема в том что вы даже не поймёте, что не так, так как таковых ошибок не будет, но что может быть не так . Поэтому, я стараюсь использовать паттерн Singleton. то есть мой код для формы будет, примерно будет таким:

var Auth = {
   submit : function(e) {
      if (VALIDATE('Auth.*')) {
        $(e.element).button('loading');      
        AJAX('POST /login', Auth.form , function(res, err) {             
            if (err) {  SET('errors', RESOURCE('!unexpected'));
                 $(e.element).button('reset');                     
                 return;
            }            
            if (res.success) {
                SET('errors', null);
                window.location = res.value.redirect;
                return false;
            }            
            $(e.element).button('reset');                     
            SET('errors', res.error||res);
            return false;            
        })    
      }    
   }    
}    
COMPILE()

или вот таким

var Reg = {
    init : function(){
        var self = Reg;
        COMPILE();
        self.mess = Ta.compile($('#taMess').html());  
        FIND('#org', (c) => initSuggestions(c.find('input'), 'PARTY', self.selectOrg));
    },      
    selectOrg : function(sug) {
        var self = Reg;
        if (!sug.data) return;
        SET('Reg.form.org', getSugCompany(sug));
    },    
    submit : function(e) {
        ...
    }    
}     
Reg.init();

Заключение

Итак, утилита Fabric на мой взгляд может быть полезна многим, это и те кто только начинает разрабатывать, учится и опытным разработчикам. А я стараюсь сложные вещи делать просто. Если у вас будет идеи, чем дополнить утилиту или что необходимо исправить я будут Вам за это признателен.

Спасибо за внимание!


Ссылки:

Категории