◄ 1 2 3 4 5 6 |
Информационные технологии
:: lsFusion
|
|
| ||
CrushBy 14.10.19 - 21:08 | В этой ветке только вопросы по lsFusion, без оценок и срача, что в сторону lsFusion, что в сторону 1С.
Для сравнения и троллинга есть отдельная ветка : OFF: lsFusion vs 1C. Раунд 3 | ||
Ещё1 501 - 29.10.19 - 13:27 | Правильное решение получения объекта по внутреннему идентификатору:
order() <- GROUP MAX Order o IF o IS Order AND LONG(o) == impID(); | ||
Bro 502 - 29.10.19 - 14:06 | (501) Да есть этот фокус, с тем что указание класса, это еще не означает IS. Хотя строго говоря в данном случаем можно класс не указывать и просто писать GROUP MAX o IF o IS Order AND LONG(o) = impID(); | ||
Ещё1 503 - 29.10.19 - 14:16 | (502) Ага, untyped implicit parameter declaration. С другой стороны, если lsFusion может вывести тип и параметры переменной из записи запроса, то почему нет. | ||
Bro 504 - 29.10.19 - 14:39 | (503) Это не warning. Это подсветка чтобы случайно новые параметры не заводили. lsFusion выводит классы параметры и значений свойств и при неявной ситуации. Просто обычно не рекомендуется не указывать классы параметров, если идет обращение к другим свойством, потому как ambigious рискуете получить, когда появится еще одно свойство с таким именем. | ||
Bro 505 - 29.10.19 - 14:40 | * при неявной типизации | ||
Ещё1 506 - 29.10.19 - 16:24 | (504) Так а в случае ambigious будет предупреждение? Если да - то не проблема. | ||
Ещё1 507 - 29.10.19 - 16:36 | Обновляется ли форма в lsFusion автоматически при изменениях в базе? На примере: в web-клиенте открыта форма со списком заказов, на сервере приложений фоновая задача отрабатывает пришедший от 1С пакет, который обновляет статус заказов. Но у пользователя в Web-клиенте статусы сами не обновляются, надо жать formRefresh. Это так задумано, или недоработка (моя или платформы)? | ||
Злопчинский 508 - 29.10.19 - 16:40 | (507) имхо это проблематично.
обновлений в базе столько может быть, что ядро должно постоянно диспетчеризировать и рассылать "уведомления" об обновлении. или клиент (с таймаутом? - это херня полная) | ||
Bro 509 - 29.10.19 - 16:52 | (507) Да проблематично, по сути надо следить как-то за видимым окном и что именно в нем произошли изменения. Оверхед будет очень большой скорее всего в таком случае.
Для реализации таких вещей обычно AUTOREFRESH используют: https://documentation.lsfusion.org/pages/viewpage.action?pageId=3670145 | ||
Ещё1 510 - 29.10.19 - 17:26 | (509) AUTOREFRESH отлично, полностью устраивает. | ||
Злопчинский 511 - 29.10.19 - 17:34 | (509) при авторефреше - сохранится набитое в текстовых поляпрочих полях которые не изменялись другой тсороной? курсор в поле вврда текста останетяс на той же строке? | ||
Bro 512 - 29.10.19 - 17:47 | (511) Естественно. | ||
Ещё1 513 - 29.10.19 - 20:48 | Зря вы сделали логины пользователей чувствительными к регистру. Он должен иметь возможность ввести Vasya, vasya или VASYA (Caps Lock "случайно" включился), и система его примет. Меньше разгневанных звонков в службу поддержки. Вот пробелы в начале и конце логина отбрасываете - это правильно. | ||
Ещё1 514 - 30.10.19 - 11:37 | Такой код:
NEW ur = UserRole { sid(ur) <- 'admin'; //... mainRole(customUser('admin')) <- ur; } Он компилируется, но в IDEA подчёркивает красным customUser('admin') и пишет Ambiguous reference: mainRole(?) and mainRole(?) match. Я уточняю тип параметра: mainRole(customUser('admin') AS CustomUser) <- ur; Но подчёркивание остаётся. Пробовал приведение к типу: mainRole(CustomUser(customUser('admin'))) <- ur; Но так не компилируется. Как избавиться от этого предупреждения? Можно и так оставить, но я люблю когда код чистый, без предупреждений компилятора. | ||
_DAle_ 515 - 30.10.19 - 12:08 | (514) Подскажите, пожалуйста, если нажать ctrl+b на mainRole в исходном коде, то показываются ссылки на исходные файлы в двух разных .jar файлах, один из которых *sources.jar? | ||
Ещё1 516 - 30.10.19 - 14:15 | |||
_DAle_ 517 - 30.10.19 - 14:40 | (516) Избавиться всегда можно с помощью явного указания сигнатуры, в данном случае mainRole[User], но ситуация ненормальная, нужно смотреть. | ||
Ещё1 518 - 30.10.19 - 14:45 | Подстановка mainRole[CustomUser](customUser('admin')) <- ur; не убирает подчёркивание. | ||
Ещё1 519 - 30.10.19 - 14:49 | https://paste.pics/81cbf7cc50a7b6a2939a2b7dc5e949b5
Меня смущают "?" в предупреждении об ошибке. Такое ощущение что плагин не видит истинных типов параметров в определениях mainRole. | ||
_DAle_ 520 - 30.10.19 - 15:15 | |||
_DAle_ 521 - 30.10.19 - 15:33 | (520) Воспроизвел баг, проявляется, когда системные модули, в том числе и Security.lsf, находятся внутри jar файла, как, видимо, и у вас сейчас. Будем разбираться. | ||
Злопчинский 522 - 31.10.19 - 00:24 | Где по типовой методе в фузине предполагается хранить картинки товаров (для веба и для десктопа). Как от рисовать хранимую картинку на форме? Типа идём по товарам по списку - меняется картинка. | ||
_DAle_ 523 - 31.10.19 - 12:24 | (522) Я, конечно, не очень знаю типовые подходы. Но в исходниках вижу, например, вот такое применение:
image 'Изображение' = DATA IMAGEFILE (Article, Color); То есть изображения хранятся в базе. Реализуется это с помощью свойства, которое возвращает объект класса IMAGEFILE. В данном случае выбор картинки зависит от артикула и цвета. Потом нужно будет добавить это свойство на форму, обычно в отдельную панель. | ||
Bro 524 - 31.10.19 - 12:30 | (522)
image = DATA IMAGEFILE (Sku); FORM skus OBJECTS s=Sku PROPERTIES (s) image PANEL ; Когда будете ходить по товарам картинка будет сама обновляться. Хранятся прямо в базе. | ||
Ник080808 525 - 31.10.19 - 12:33 | (524) если нужно прикреплять несколько картинок к товару? к строке документа? | ||
CrushBy 526 - 31.10.19 - 12:43 | (525) Несколько картинок :
CLASS Image; sku = DATA Sku (Image) NONULL DELETE; file = DATA IMAGEFILE (Image); Прикрепление к строке документа : image = DATA IMAGEFILE (DocumentLine); | ||
Ник080808 527 - 31.10.19 - 12:47 | (526) по какому ключу связывается картинка и строка? по номеру строки? | ||
CrushBy 528 - 31.10.19 - 12:52 | (527) Смотрите, IMAGEFILE - это просто примитивный тип. Вроде строки. В базе данных она хранится как byte array (то есть просто бинарным файлом). Соответственно просто в строке появляется новое поле. Как правило, мы складываем их в отдельную таблицу, чтобы не раздувать основную таблицу со строками :
TABLE documentLineImage(DocumentLine); image = DATA IMAGEFILE (DocumentLine) TABLE documentLineImage; | ||
Ещё1 529 - 31.10.19 - 13:15 | Непонятно, как показать в карточке товара все его картинки. Например, автомобиль, снятый с разных ракурсов. Тут можно разную логику придумать, например по-умолчанию выводится 1-я прикреплённая картинка. Щёлкая по картинке - открывается новое окно с галереей картинок по товару. | ||
Bro 530 - 31.10.19 - 15:02 | (529) Можно либо в таблице сделать и увеличить размер ряда, либо что логичнее объектами-в-колонки:
image = DATA IMAGEFILE (Car, LONG); FORM carWithPhotos OBJECTS c=Car, l=LONG FILTERS image(c, l) // фильтруем только номера с картинками PROPERTIES image(c,l) COLUMNS (l) HEADER 'Фото ' + l ; По идее должно сработать Рекламное место пустует | ||
Ещё1 531 - 31.10.19 - 15:08 | (530) Т.е. в таблицы можно не только текст выводить, но и картинки? | ||
Злопчинский 532 - 31.10.19 - 16:34 | (470) я согласен, но настройки интерфейса - зачем на них разработчика тащить. если у меня на ноуте по вертикали 800 пикселей экран - мне бы верхнее меню вообще значки убоать и оставить только текст.
. аналогично - левая панель перечень справочников\документов - хорошо бы разные пиктограммы иметь и убрать текстт - я по горизонтали сэкономлю... | ||
Злопчинский 533 - 31.10.19 - 16:37 | (531) не, в таблицы картинкт колонками выводить это в отчет хорошо. а на экране - как показать ленту картинок для текущей строки таблицы\списка?понятно что в ленте может быть переменное колво картинок для разных строк списка. | ||
Bro 534 - 31.10.19 - 16:38 | (531) ну все можно везде выводить. Строго говоря, с точки зрения реализации свойство в панели это таблица из одного ряда, одной колонки, без заголовка. Вопрос что у разных типов разные рендереры. У картинок это отображение картинки. | ||
Bro 535 - 31.10.19 - 16:39 | (533) для этого объекты-в-колонки использовать. То есть по сути кросс-таблицы, просто в панели эта таблица из одного ряда. | ||
Ещё1 536 - 01.11.19 - 01:42 | Воспользовался предложением CrushBy в соседней ветке ( OFF: lsFusion vs 1C. Раунд 7 (37) ) и переделал обновление справочника товаров, как приведено в примере №3 https://documentation.lsfusion.org/pages/viewpage.action?pageId=46367614
И сравнил по скорости с первоначальным решением "в лоб". В качестве теста делал 3 загрузки каталога: сначала 1-ю половину, потом 2-ю, а потом целый каталог товаров. Действительно, загрузка ускорилась практически ровно в 2 раза. | ||
CrushBy 537 - 02.11.19 - 11:17 | К сожалению, оптимизация получилась не полной. В общем случае FOR может скомпилироваться в один SQL запрос (а не выполняться на сервере приложений), если в нем нет IF'ов, других FOR'ов и строки записи внутри его не зависят друг от друга. У Вас же получается, что внутри пробега создаются группы, производители и прочие. Для оптимизации нужно вынести создание справочников за пределы FOR'а.
Например, с импортом групп снаружи FOR будет другой цикл по созданию несуществующих групп : FOR [GROUP MAX INTEGER i BY groupName(i)](ISTRING[100] name) AND NOT groupByName(name) NEW g = Group DO { name(g) <- name; } GROUP MAX тут используется потому, что идет импорт из денормализованной таблицы, и одна группа в строках встречается несколько раз. Соответственно, создавать группу нужно один раз. Потом уже при заполнении свойств sku там останется только group(u) <- groupByName(groupName(i)); так как все группы уже созданы в предыдущем FOR'е. Это все приведет к тому, что все пойдет одним запросом и импорт должен ускориться во много раз. | ||
Bro 538 - 02.11.19 - 12:23 | (537) IF'и и FOR'ы тоже отлично компилируются в "один запрос" (ELSE'ы только пока не компилируются). Главное чтобы зависимостей читающих свойств от свойств в которые пишется не было. Хотя там можно INLINE в FOR поставить и тогда :
FOR f(a) INLINE DO g(a) <- h(g(a)); Скомпилируется в WHERE (то есть один запрос): g(a) <- h(g(a)) WHERE f(a); принудительно. Но нужно понимать, что при этом может поменяться логика (собственно поэтому платформа этого и не делает). INLINE пока единственная (или одна из 2-3) опция которая не описана в документации, так как для этого нужно подробнее описывать как все работает. Это мы конечно тоже сделаем, но чуть позже. | ||
Ещё1 539 - 02.11.19 - 18:10 | Я собирался вынести обновление вспомогательных справочников отдельно. Но почему-то показалось, что несколько пробегов типа FOR groupName(INTEGER i) ... по загруженным данным будут хуже 1 пробега FOR id(SKU u) == skuID(INTEGER i), пусть с проверками внутри. А надо было проверить, разница очень заметная. Если до изменений тест пробегался за 16145 мс и 14379 мс (1-я и последующие итерации), то после выноса обновлений справочников - 2688 мс и 1743 мс соответственно. Выигрыш в 6-8 раз. Получается импорт стал быстрее в 12-16 раз по сравнению с решением "в лоб".
Может, немного сбил синтаксис локальных свойств, что вместо groupName = DATA LOCAL ISTRING[100] (INTEGER); нужно писать LOCAL groupName = ISTRING[100] (INTEGER); Я протестировал сейчас 4 варианта: с циклами типа FOR groupName(INTEGER i)..., циклы FOR [GROUP MAX INTEGER i BY groupName(i)](name), и те же циклы с добавлением INLINE. По скорости они все примерно одинаковы. Может только FOR groupName(INTEGER i)... без INLINE чуть медленнее, но нужны значительно большие тестовые справочники, чтобы утверждать точно. С INLINE мне не совсем понятно. Есть ли небольшое ускорение, или и без INLINE компилятор нормально справился в данном случае. Небольшое наблюдение. В операторе [GROUP MAX INTEGER i BY groupName(i)](ISTRING[100] name) Я бы предпочёл не указывать тип параметра ISTRING[100]. И я вижу, язык это позволяет. Причина: при изменении размерности или типа исходного свойства (например на STRING[200]) при явном указании типа в (ISTRING[100] name) придётся вручную отыскать все такие использования и откорректировать. | ||
tty12 540 - 02.11.19 - 18:46 | (538) (537)
Может уже спрашивали, но я ответа не видел... И все с начала читать лень. Конкретный, простой вопрос. Вы зарубу (задачи в ней) сделали? На котрую Вы подписались! Где решение? Под ТЗ решение, а не под оду... У вас есть ответ? PS: Я вижу один и тот же ответ - 1. "Три сточки дописать." - это всегда!!! 2. "Джун косячит..." - хотя Краш клялся за ним следить, "как за собой" - его цитата. 3. "Краш оду пишет..." - нахер она кому нужна тут???? Речь не про оду... 4. А надо ли продолжать? Фузинаторы - Вы дурачки? | ||
CrushBy 541 - 03.11.19 - 13:45 | (539) Я тут немного понял вот что, делать вот так вроде как нельзя :
FOR groupName(INTEGER i) AND NOT groupByName(groupName(i)) NEW g = Group DO { name(g) <- groupName(i) } Поскольку, если это не будет скомпилировано в один запрос, то сначала вычисляется выражение, а затем идет по нему итерирование уже на сервере приложений. Так как таблица денормализованна, то создастся несколько групп с одинаковым именем и сохранение не пройдет по CONSTRAINT. Поэтому в моем примере шел GROUP MAX. В целом важно понимать, что нужно стремиться, чтобы все компилировалось в SQL запрос, так как выполнение на сервере БД значительно быстрее чем round trip между сервером приложений и сервером БД. [Может, немного сбил синтаксис локальных свойств, что вместо groupName = DATA LOCAL ISTRING[100] (INTEGER); нужно писать LOCAL groupName = ISTRING[100] (INTEGER);] Эти два объявления с точки зрения выполнения идентичны. Разница в том, что второе объявление видно только в пределах действия, а первое - в пределах модуля и зависимых от него модулей. [С INLINE мне не совсем понятно. Есть ли небольшое ускорение, или и без INLINE компилятор нормально справился в данном случае.] Итерирование на большом объеме в любом случае медленнее, если с INLINE они одинаковы, то или INLINE не сработал и запрос не скомпилировался, или наоборот, исходный скомпилировался. Вообще, с точки зрения выполнения это хорошо видно по "бегунку" в GUI. При итерировании будет идти бегунок, когда выполняется SQL запрос, то никакого бегунка быть не может, так как SQL запрос не возвращает данные о статусе своего выполнения в данный момент. [Я бы предпочёл не указывать тип параметра ISTRING[100]]. Да, там можно не указывать. Платформа должна в таком случае вывести тип сама (если получится). | ||
Salimbek 542 - 08.11.19 - 16:58 | Тут Конкретные вопросы по lsFusion
Это: // можно сделать хитрее, i2 закинуть в колонки выдаст матрицу 10x10 в ней будут значения REQUIRE Utils; // Моя добавка, т.к. iterate в utils FORM a OBJECTS i1=LONG PROPERTIES VALUE(i1) OBJECTS i2=LONG PROPERTIES a(i1,i2) COLUMNS (i2) HEADER (i2) FILTERS iterate(i1,1,10), iterate(i2,1,10) ; run() { a(1,2) <- 5; a(4,2) <- 7; a(1,3) <- 9; SHOW a; } Пробую выполнить код на lsfusion.org/try - открывается пустое приложение, SHOW a не срабатывает? Ну ок, запускаю IDEA, копирую туда этот код, в ответ: ERROR StartLogger - Exception while starting logics instance: [error]: Main:11:5 single parameter is forbidden in this context Subsequent errors (if any) could not be found. Как я понял - это оно на HEADER (i2) ругается, но как и где поправить? | ||
Ёпрст 543 - 08.11.19 - 18:12 | (542) тестиь платформу ? Я чегой-то подзабил, хотя и развернул и демку с ерп даже запустил, лень | ||
Bro 544 - 08.11.19 - 18:32 | (542) Вообще сейчас не у компьютера, но по идее можно написать HEADER (i2+1-1) :) То есть ей не нравится в этом месте параметр, там да косяк был в этом месте. На самом деле в 2.1 это уже пофикшено ЕМНИП и даже уже релиз ее был. На сайте ссылки новые на нее не добавили. Хотя на download.lsfusion.org уже есть. | ||
CrushBy 545 - 08.11.19 - 18:51 | (542) Если речь идет о запуске в Try, то вот модифицированный код, который работает :
REQUIRE Utils; // Моя добавка, т.к. iterate в utils a = DATA LONG (LONG, LONG); FORM a OBJECTS i1=LONG FILTERS iterate(i1,1,10) OBJECTS i2=LONG PROPERTIES a(i1,i2) COLUMNS (i1) HEADER (i1) FILTERS iterate(i2,1,10) ; NAVIGATOR { NEW a; } | ||
Bro 546 - 08.11.19 - 19:13 | (542) а понял теперь. На Try уже свежая версия 3.beta.0 (поэтому на HEADERS (i2) не ругается), а в инсталляторе вы 2.0 ставили где да была такая проблема.
А не запускается потому как run() в режиме платформы ничего не значит, это вы просто объявили действие с именем run. Оно играет роль в режиме СУБД (а точнее оператора EVAL или HTTP вызова eval например, который и выполняет EVAL) - там выполняется именно действие с именем run. https://documentation.lsfusion.org/pages/viewpage.action?pageId=4915350 https://documentation.lsfusion.org/pages/viewpage.action?pageId=51216539 | ||
Salimbek 547 - 12.11.19 - 14:52 | (546) И как обновиться с 2.0 до "3.beta.0" или чего там у вас самое новое? | ||
Bro 548 - 12.11.19 - 15:13 | (547) Последние snapshot версии вот тут (файлы с постфиксом assembly, это jar файлы все-в-одном вместе с зависимостимя ):
Сервер: https://repo.lsfusion.org/nexus/service/rest/repository/browse/public/lsfusion/platform/server/3.beta.0-SNAPSHOT/ Десктоп-клиент: https://repo.lsfusion.org/nexus/service/rest/repository/browse/public/lsfusion/platform/desktop-client/3.beta.0-SNAPSHOT/ Веб-клиент: https://repo.lsfusion.org/nexus/service/rest/repository/browse/public/lsfusion/platform/web-client/3.beta.0-SNAPSHOT/ Инструкции тут в разделе Обновление: https://documentation.lsfusion.org/pages/viewpage.action?pageId=57738078 Пока 3.beta.0 не выпускали, но в ближайшее время выпустим, тогда просто в download.lsfusion.org появится. |
◄ 1 2 3 4 5 6 |
Список тем форума
|