Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
zol4git
@zol4git
в таком виде
data: {
    sum: agr.value
  },
binding: {
  sum: 'data:'
}
Roman Dvornov
@lahmatiy
Всем привет!
Value#as() будет обновляться только когда поменяется значение, от которого вычисляется значение. В переданной функции создается индекс, но возвращается статическое значение; то есть нет никаких намеков, что нужно перевычислять as например, потому значение остается прежним
compute и pipe в ваших примерах использованы таким образом, что они заставляют пересчитать при изменении числа элементов в наборе, но не при изменении поля элемента
Тут в том, что нужно получить индекс и подсунуть его в биндинг (в данном случае). При этом не нужно обращаться к Index#value – так как оно вернет текущее значение индекса, для обновлений надо подписываться
Сейчас напишу как должно быть...
Roman Dvornov
@lahmatiy
const { Value, Dataset, wrap } = require('basis.data');
const { sum } = require('basis.data.index');
const { Node } = require('basis.ui');

const dataset1 = new Dataset({ items: wrap([1,2,3,4,5,6], true) });
const dataset2 = new Dataset({ items: wrap([1,2,3], true) });

new Node({
    container: document.body,
    template: `
        <div>
            {sum}
            <button event-click="swap">swap datasource</button>
            <button event-click="update">update random item</button>
        </div>
    `,
    dataSource: dataset1,
    binding: {
        sum: sum(Value.query('dataSource'), 'data.value')
    },
    action: {
        swap: function() {
            this.setDataSource(this.dataSource === dataset1 ? dataset2 : dataset1);
        },
        update: function() {
            this.dataSource.forEach(x => x.update({ value: Math.random() }))
        }
    }
});
То есть
Value.query('dataSource').as(ds => DataIndex.sum(ds, 'data.field_num').value)
=>
DataIndex.sum(Value.query('dataSource'), 'data.field_num')
zol4git
@zol4git
@lahmatiy Спасибо, Роман, просто супер! Не бросайте basis.js, а то что-то никакого шевеления за последние полгода. Понравилось как вы ответили на вопрос в подкасте " - React, Vue или Angular?" - " - basis.js". Может дождёмся и версии 2.0.
Alexey Smirnov
@sm0g
@zol4git можно ссылку на подкаст?
zol4git
@zol4git
@sm0g хорошо, я не сохранил, завтра поищу, сегодня уже сил нет, точно не помню в конце прошлого года было или в этом уже.
@sm0g а нет, быстро нашлось https://soundcloud.com/frontend-weekend/fw-25
Alexey Smirnov
@sm0g
@zol4git спасибо
NightFox
@0x4E69676874466F78
Приветствую, недавно начали доходить руки до базиса.
Пишу движок для некоторых сообществ, и для фронта есть потребность в пользовательских скриптах расширяющих имеющийся функционал, то есть в скриптах под базис которые асинхронно подключаются по требованию уже после сборки в бандл.
Я вижу есть патчи, но как их правильно подключать на лету?
Читал про виртуальные ресурсы но это что-то не то.
@lahmatiy, @smelukov
Sergey Melyukov
@smelukov
@0x4E69676874466F78 привет! Можно подробнее? ;)
Ребят, такой вопрос - что, на ваш взгляд, самое удобное в базисе? И наоборот - что самое неудобное?
Alexey Smirnov
@sm0g
@smelukov привет. Мой список:
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 с удовольствием посмотрю. Надеюсь, что в скором времени и я презентую свой проект =)