Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Alexey Smirnov
@sm0g

Что нравится:

  1. Template live reload
  2. <b:include> и композиция шаблонов
  3. Изоляция CSS
  4. basis.data: DataObject, DataSet, Filter
  5. Работа с Selection
  6. Реактивные значенния: Value, Token
  7. Локализация шаблонов
  8. Динамические сателлиты
  9. Делегирование данных
  10. STATE контролов
  11. Компактность билда после сборки

Что вызывает вопросы:

  1. Работа с реактивными значениями. Не всегда понятно почему биндинги не отрабатывают. Кроме DataFlow примера хотелось бы описания.
  2. Хотелось бы более сложного примера приложения, чтобы понять best practices.
  3. Хочется понять как лучше создавать Test Driven UI компоненты. Я использую yatra, sinon и проч.
  4. Наследование в Entity. Как я понял его нельзя реализовать по аналогии с Node.subclass.
  5. Хотелось бы TypeScript, но это уже пожелание =)
novicov
@novicov
Всем привет. Можете помочь, нужно сделать загрузку файлов, изображений на сервер. Есть ли примеры на basisjs ? Или доки по данной теме
Alexey Smirnov
@sm0g
@novicov, привет. Недавно делал загрузку изображений с превью. Буду у компа скину пример.
novicov
@novicov
@sm0g спасибо)
Alexey Smirnov
@sm0g
@novicov JS для аплоадера:
const Field = require('app.ui.common.field').Field;
const Preloader = require('app.ui.common.preloader');
const DomEvent = require('basis.dom.event');
const FileUploader = require('basis.net.upload').FileUploader;
const Config = require('app.config');
const STATE = require('basis.data.state');
const arrayFrom = basis.array.from;

const ImageUploader = Field.subclass({
  template: resource('./templates/imageUploader.tmpl'),
  init: function() {
    Field.prototype.init.call(this);

    this.fileUploader = new FileUploader({
      handler: {
        start: () => this.setState(STATE.PROCESSING),
        success: (self, request, response) => {
          this.setState(STATE.READY);
          this.setValue(response.data);
        }
      }
    });
  },
  uploadUrl: '',
  data: {
    hovered: false,
    uploading: false
  },
  binding: {
    objectId: node => node.basisObjectId,
    hovered: 'data:',
    preloader: 'satellite:'
  },
  satellite: {
    preloader: {
      instance: Preloader,
      events: 'stateChanged',
      existsIf: (owner) => owner.state == STATE.PROCESSING
    }
  },
  templateSync: function(){
    Field.prototype.templateSync.call(this);

    let dropZone = this.tmpl.dropZone;
    let fileInput = this.tmpl.fileInput;

    arrayFrom(['dragenter', 'dragover', 'dragleave', 'drop']).forEach((eventName) => {
      DomEvent.addHandler(dropZone, eventName, this.preventDefaults, this)
    });
    arrayFrom(['dragenter', 'dragover']).forEach((eventName) => {
      DomEvent.addHandler(dropZone, eventName, this.highlight, this)
    });
    arrayFrom(['dragleave', 'drop']).forEach((eventName) => {
      DomEvent.addHandler(dropZone, eventName, this.unhighlight, this)
    });
    DomEvent.addHandler(dropZone, 'drop', this.dropHandler, this);
    DomEvent.addHandler(fileInput, 'change', this.fileSelectionHandler, this);
  },
  highlight: function () {
    this.update({ hovered: true })
  },
  unhighlight: function () {
    this.update({ hovered: false })
  },
  preventDefaults: function(e) {
    e.preventDefault();
    e.stopPropagation();
  },
  dropHandler: function (e) {
    let dataTransfer = e.dataTransfer;
    let file = dataTransfer.files[0];

    this.processFile(file);
  },
  fileSelectionHandler: function () {
    let fileInput = this.tmpl.fileInput;
    let file = fileInput.files[0];

    this.processFile(file);
  },
  processFile: function (file) {
    let reader = new FileReader();

    reader.readAsDataURL(file);
    reader.onload = () => {
      this.setValue(reader.result);
      if(this.uploadUrl !== '')
        this.fileUploader.uploadFiles(Config.API_HOST + this.uploadUrl, [file], 'file');
      // else
      //   this.setValue(reader.result);
    };
    reader.onerror = (error) => {
      console.log('Error: ', error);
    };
  },
  action: {
    removeIcon: function (e) {
      e.preventDefault();

      let fileInput = this.tmpl.fileInput;

      fileInput.value = '';
      this.setValue('');
    }
  }
});

module.exports = ImageUploader;
шаблон
<b:style src="./imageUploader.css" />
<b:style src="/app/ui/common/icon/templates/icon.css" ns="icon"/>
<b:l10n src="/app/l10n/imageUploader.l10n"/>
<b:define name="hovered" type="bool"/>
<b:isolate/>

<b:include src="app.ui.common.field.Field">
  <b:replace ref="fieldPlace">
    <div class="imageUploader">
      <form>
        <input{fileInput} type="file" name="file" id="imageUploader_{objectId}" class="imageUploader__fileInput" accept="image/*"/>
        <label class="imageUploader__label" for="imageUploader_{objectId}">
          <div{dropZone} class="imageUploader__dropZone _{hovered}">
            <img src="{value}" class="imageUploader__image" b:show="{value}"/>
            <b:svg use="#icon-picons-photo" class="icon:svg imageUploader__icon" b:hide="{value}"/>
            <!--{preloader}-->
          </div>
          <div class="imageUploader__hint" b:hide="{value}">{l10n:clickToUpload}</div>
          <div class="imageUploader__hint" b:show="{value}" event-click="removeIcon">{l10n:clickToRemove}</div>
        </label>
      </form>
    </div>
  </b:replace>
</b:include>
CSS
@import "variables";

.imageUploader {
  width: 108px;
  cursor: pointer;

  &__dropZone {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 108px;
    height: 108px;
    font-size: 45px;
    background: $grey-ultra-light;
    border: 2px dashed $grey-light;
    border-radius: 10px;
    overflow: hidden;
  }

  &__dropZone._hovered {
    border: 2px solid $green-primary;
    opacity: 0.5;
  }

  &__image {
    max-width:100%;
    max-height:100%;
    pointer-events: none;
  }

  &__fileInput {
    position: absolute;
    top: 0;
    left: -10000px;
    opacity: 0;
  }

  &__icon {
    stroke-width: 0.1;
    color: $grey-light;
  }

  &__dropZone._hovered &__icon {
    color: $green-primary;
  }

  &__label {
    display: block;
    cursor: pointer;
  }

  &__hint {
    display: block;
    padding-top: 5px;
    line-height: 15px;
    color: $blue-primary;
    font-size: 12px;
    text-align: center;
  }

  &__hint:hover {
    text-decoration: underline;
  }
}
novicov
@novicov
@sm0g спасибо, буду тестировать
NightFox
@0x4E69676874466F78

@smelukov Прошу прощения за задержку в ответе, жизненные обстоятельства.
Попробую иначе сформулировать.
В базисе при конечной сборке (в продакшен) все js-файлы сборщиком пакуются в единый образ и после сборки динамически файлы подгрузить нельзя, о чём явно написано в документации:

Содержимое ресурсов считается частью программы (приложения), как если бы его содержимое был указано непосредственно в коде. По этой причине ресурсы загружаются синхронно, не могут быть внешними (по отношению к приложению) или быть динамическими (результатом выполнения серверного скрипта). После выполнения сборки содержимое ресурсов встраивается в основной код приложения и не загружаются отдельно. Особый случай – виртуальные ресурсы, которые не привязаны к конкретному файлу.

Но у меня есть потребность подгрузить ряд скриптов динамически уже после сборки. Эти скрипты могут расширять шаблоны и существующую логику.
Например в карточной игре worldoftanks general есть подобный функционал https://habr.com/company/wargaming/blog/271357/ и я хочу нечто похожее с базисом.
В документации к базису упоминаются некие виртуальные ресурсы, но как их использовать я не понял.
У меня была мысль подгружать скрипты минуя сам базис и там проникая через глобальную видимость уже патчить, но это как-то показалось некрасиво, поэтому решил спросить тут.

NightFox
@0x4E69676874466F78
Вроде разобрался с этими виртуальными ресурсами, только не понятно как update работает для них, у меня она не срабатывает, впрочем в моём случае оно наверное не очень применимо.
NightFox
@0x4E69676874466F78
только не ясно как добираться до компонентов из виртуального ресурса без явного их экспорта в window
Ilya
@agoalofalife
@0x4E69676874466F78 Удалось разобраться?
NightFox
@0x4E69676874466F78
@agoalofalife привет, ну я остановился на экспорте в window нужных мне компонентов, то есть делаю аджаксом запрос на скрипт, вставляю результат в виртуальный ресурс и фетчу его, дальше уже из под виртуального ресурса делаю с экспортированными компонентами что мне нужно.
Подозреваю что чтобы пробрасывать внутрь виртуального ресурса ссылки без лишнего гемора мне надо модифицировать саму функцию создания виртуальных ресурсов базиса.
Ещё вариант приходит в голову обходная магия с методом ready, где можно вызывать свою функцию на патчинг нужных частей кода и пробросом туда ссылок на компоненты.
Но пока не хочется тратить много усилий на эти эксперименты, сейчас это не принципиально.
Ilya
@agoalofalife
@0x4E69676874466F78 круто что разобрался, у меня опыта не было с виртуальными ресурсами, ну я так вчера чу чуть их подрогал ради интереса)а зачем тебе такие кастомизации ?
NightFox
@0x4E69676874466F78
@agoalofalife да тут на самом деле ничего сильно сложного нет, если брать по отдельности, просто мне такой фреймворк сразу проглотить очень тяжело, в голове каша и дезориентация на первых этапах была.
Ну это не мне, это продвинутым пользователям. Бывают ситуации когда кому-то что-то нужно, но в апстрим это тащить смысла нет, а юзерскрипты (типа все эти разновидности greasemonkey) это ненадёжно.
Ilya
@agoalofalife
ок, ты если что пиши здесь)а то нас и так мало(
NightFox
@0x4E69676874466F78
ага, я потом опубликую тут ссылку на проект
Ilya
@agoalofalife
это комерческий или свой?
NightFox
@0x4E69676874466F78
свой но тут не так всё однозначно, я пишу веб-движок на го+базис, планирую его использовать как для некоммерческой деятельности так и возможно коммерческой (пока точно не уверен), то есть на движке несколько проектов, опубликую я тот что некоммерческий.
Ilya
@agoalofalife
круто а в чем его назначение?
NightFox
@0x4E69676874466F78
@agoalofalife ну я писал выше что это движок сообществ (на данный момент, так-то он только ими не ограничивается), в большей мере неформальных, коротко его охарактеризовать весьма сложно, в нём решаются разные социально-организационные проблемы, помимо прочего есть большой уклон в структуризацию, классификацию, в целом более правильное управление контентом-данными. Это пока что всё что я могу сказать.
Ilya
@agoalofalife
ok)
NightFox
@0x4E69676874466F78
потом ещё планируется федерализация системы, типа как у matrix (matrix.org) и подобных сетей
Alexey Smirnov
@sm0g
@0x4E69676874466F78 если будут еще вопросы пишите. Я сем смогу помогу :р
Ilya
@agoalofalife
@sm0g круто что еще здесь))еще используешь basis?
Alexey Smirnov
@sm0g
У меня уже столько кода написано, что проще застрелиться, чем перейти на что-то другое. Да и базис мне нравится.
@0x4E69676874466F78
@agoalofalife
Ilya
@agoalofalife
@sm0g один на проекте?
Alexey Smirnov
@sm0g
@agoalofalife да, один
NightFox
@0x4E69676874466F78
@sm0g буду иметь ввиду, спасибо
zol4git
@zol4git
Люди! Что происходит с basis.js? проект совсем заглох? Кто что пишет на нём? На следующей неделе планирую показать свой проект, хелп нужно дописать.
В принципе сам пользуюсь уже год, но для общего применения ещё кое-чего не хватает.
Alexey Smirnov
@sm0g
Привет. Видимо, авторы забросили проект. Я пишу свой проект и доволен. С удовольствием посмотрю твой :smile:
zol4git
@zol4git
@sm0g Привет. Да я тоже многим доволен, но хотелось бы и развития, и не очень хочется на что-то другое переходить (хотя видимо придётся, но не react или vue однозначно). Пока дописываю хелп, но можно посмотреть вживую https://memoriz.app - сервис для хранения коллекций документов произвольной структуры в облаке или локально (синхронизации пока нет). Регистрация пока отключена, но можно работать в "Локально - Анонимные", хотя без описания конечно мало будет понятно. Можно посмотреть "Тесты и примеры" и другие "Публичные" коллекции. С удовольствием отвечу на вопросы и пожелания, но лучше не здесь (чтобы не засорять). Если будет интерес открою регистрацию и создам "Совместную" коллекцию для общения, типа простенькой конференции, или предложите другое.
Alexey Smirnov
@sm0g
@zol4git с удовольствием посмотрю. Надеюсь, что в скором времени и я презентую свой проект =)
zol4git
@zol4git
@sm0g Может есть кто живой. Сделал в своём проекте https://www.memoriz.app поддержку Markdown, для примера залил документацию по basis с githuba (раздел Программирование - Javascript ...), может кому будет полезно. Было бы интересно посмотреть что ещё делается на basis.
Roman Dvornov
@lahmatiy

@sm0g Может есть кто живой. Сделал в своём проекте https://www.memoriz.app поддержку Markdown, для примера залил документацию по basis с githuba (раздел Программирование - Javascript ...), ...

Здорово :+1:

Alexey Smirnov
@sm0g
@zol4git =)) Живее всех живых. Какую библиотеку использовали для Markdown?
zol4git
@zol4git
@sm0g Взял за основу https://adamvleggett.github.io/drawdown/ и немного (на самом деле много) допилил на скорую руку (пока без индексов и таблиц). Всё остальное либо тяжёлое, либо кривое.
@sm0g А как ваш проект поживает?, тоже было бы интересно посмотреть
zol4git
@zol4git
Всем неравнодушным, если нравится проект - делайте пожертвования (ссылка в helpe), крайне необходимы средства на дальнейшее развитие!
Roman Dvornov
@lahmatiy
Как вы могли заметить, я отошел от развития basis.js. На то есть ряд причин...
Были разные мысли о том, чтобы фреймворк значительно переделать – упростить, осовременить и тд. Но и без этого его нужно поддерживать и развивать. У меня нет возможности этим заниматься, но если кто-то готов взяться за развитие – давайте обсудим, передам управление проектом в добрые руки.
zol4git
@zol4git
@lahmatiy Очень жаль, что такой замечательный проект не развивается, но я не думаю, что найдется человек достаточной компетенции, чтобы заменить вас.
Alexey Smirnov
@sm0g
@zol4git @lahmatiy Переписывание, развитие фреймворка - тяжкий труд. Хотя было бы круто переписать на TypeScript. Роман, на каком фреймворке вы сейчас остановились?
Roman Dvornov
@lahmatiy
Вопрос не в том чтобы меня заменить, а чтобы обеспечить развитие проекта...
Сам сейчас занимаюсь проектами более общего плана, большинство которых, кстати, вышли в том или ином виде из basis.js или задач с ним связанных
Переписывание на TS особого профита не даст, на мой взгляд есть проблемы более актуальные.
Я в целом фреймворк-агностик, все фреймворки в той или иной степени "не торт". Basis во многих моментах выигрышнее, но устарел (хотя скорее отстал от авангарда технологий) и многое уже можно сделать проще (не надо поддерживать легаси, есть новые API и возможности JS)
Roman Dvornov
@lahmatiy
Проект которым сейчас увлечен больше всего – это Discovery, большой композитный проект, делается без фреймворков, просто чистый JS, CSS, HTML & DOM. Все гуд, разве что изоляции стилей не хватает :) хотя можно Shadow DOM попробовать применить, но пока не заморочил на это.
zol4git
@zol4git
@lahmatiy Discovery интересный проект, слежу за ним, пока нет времени посмотреть код. Мой проект немного похож, тоже работа с массивом JSON, тоже можно задавать представление и делать выборки, но больше упор на один документ. А вот Jora скорее всего пригодится в дальнейшем. А может у вас из Discovery родится микро-фреймворк или библиотека визуализации данных (вот сразу была такая надежда).
Ilya
@agoalofalife
Да жаль конечно что фрейм не получил развития.
Суровая реальность токова, что без финансирования далеко сложно уехать
А так же наверное подкачала рекламная часть фрейма
Но для настоящих "true" программистов которые не побоялись в него окунуться, будет cлужить примером высокого уровня проектирования и композиции.
Хнык.. ушел плакать под одеяло(