...

Передача контекстной переменной содержащей массив объектов в свою таблицу

Тема в разделе "Вопросы по платформе", создана пользователем ybgr111, 4 апр 2022.

  1. ybgr111

    ybgr111 Участник

    Добрый вечер, столкнулся со следующей проблемой:
    Имею два приложения - одно является дочерним элементом другого по типу один ко многим. Задача - отобразить на форме просмотра элемента приложения таблицу, содержащую информацию по всем элементам дочернего приложения.

    Если брать обычный виджет "Таблица", то как я понял он может отобразить только все элементы приложения.

    Если я работаю с типом данных таблица, то проблем нет, в сценарии получаю информацию о приложении, заношу все в поля контекстной переменной и вывожу при помощи UI.widget.contextValue в виджет коде.

    [​IMG]


    Но мне нужно было еще навесить на таблицу scroll, а также другие фитчи и я не осознал как могу это реализовать здесь.
    Поэтому я решил самостоятельно написать таблицу.

    Проблема в том что при помощи UI.widget я не могу, как я понял, обратиться к элементу массива контекстной переменной и поэтому выводится сразу весь список элементов массива в одной ячейке. А мне необходимо заполнить каждую ячейку таблицы. Я начал получать [object Object] при моих попытках вывода при помощи сценария, но после придумал создать переменную произвольного типа, занести туда все существующие дочерние элементы приложения и при помощи цикла в ejs, вывести частично информацию.

    Код:
    
    async function onInit():Promise <void> {
        
    await load_table()
    }

    async function load_table():Promise <void> {

    const 
    sections await Context.fields.razdely.fetchAll()
    ViewContext.data.testovaya sections

    }

    HTML:
    <div class="scroll-table">
        <table>
            <thead>
                <tr>
                    <th>Разделы</th>
                    <th>Описание</th>
                    <th>Дата создания</th>
                    <th>Создан</th>
                    <th>Дата редактирования</th>
                    <th>Редактирован</th>
                </tr>
            </thead>
        </table>  
        <div class="scroll-table-body">
            <table>
                <tbody>
                    <% for (const item of ViewContext.data.testovaya) { %>
                    <tr>
                        <td> <%= item.data.__name %> </td>
                        <td> <%= item.data.opisanie %> </td>
                        <td> <%= item.data.__createdAt.format("hh:mm:ss DD/MM/YYYY") %> </td>
                        <td> <%= item.data.__createdBy %> </td>
                        <td> <%= item.data.__updatedAt.format("hh:mm:ss DD/MM/YYYY") %> </td>
                        <td> <%= item.data.__updatedBy %> </td>
                    </tr>
                    <% }
                    %>
    
                </tbody>
            </table>
        </div>  
    </div>



    [​IMG]

    Также я опять получаю [object Object] у пользователя, так как опять идет преобразование объекта в строку. Вопрос: могу ли я отобразить ссылки на элементы приложения и пользователей? Также буду рад, если кто-то поделится альтернативой, как можно реализовать то, что я описал выше. На платформе я новичок и скорее всего что-то упускаю из виду.

    Благодарю за прочтение.
  2. sobolev

    sobolev Техническая поддержка

    Добрый день!

    Возвращение [object Object] обосновано - система содержит в этих свойствах ссылки на другие объекты системы, в том числе на пользователей. Можно, попробовать применять к данным ссылкам метод получения цели ссылки - пример (await Context.data.user.fetch()).data.name. Таким образом можно получать данные объекта, который в виде ссылки.
  3. ybgr111

    ybgr111 Участник

    В сценариях покопался и потестил по вашему примеру fetch и смог дорыться до пользователя.
    Код:
    
    const test = (await (await Context.data.razdely![i].fetch()).data.__createdBy.fetch()).data.__name
        
    Но ведь я не могу использовать асинхронный метод await в ejs. И в контекстных переменных я так вижу нет возможности создания массивов, поэтому я не совсем понимаю как я могу отобразить эти данные в таблице. При этом нужно, чтобы сами объекты отображались в таблице как ссылки, чтобы на них можно было перейти.
  4. sobolev

    sobolev Техническая поддержка

    Возможно в таком случае, нужно использовать не строки и в них записывать имя, а назначить колонки (свойства) таблицы соответствующими типа приложений и записывать туда ссылки на объекты. В Вашем случае это будут свойства "Создан" и "Редактирован", сделать их типа "Пользователь" и записывать в них пользователей, раз Вам необходимы ссылки.
  5. sobolev

    sobolev Техническая поддержка

  6. ybgr111

    ybgr111 Участник

    Немного не понял, что вы имели в виду. То есть в собственно писанной таблице я тоже могу каким-то образом прикреплять свойства таблицы соответствующими типа приложений?

    Отвлекался на сессию, а так в целом у меня получилось сделать то что хотел
    [​IMG]

    Получилось вывести кликабельные ссылки в таблицу, но явно нерациональным способом, потому что для подгрузки всего 18 элементов требуется около 5 секунд, что просто вводит меня в депрессию. (Таблица самописная, стили попытался сделать, как у обычной виджет таблицы).


    Я просто взял и завел в сценарии два массива типа string, при помощи fetch дождался получения имен пользователей и запушил в эти массивы все результаты. После чего приравнял их viewcontext переменным произвольного типа и при помощи вставок ejs навел, как по мне, ужасный, но рабочий код. Также попытался поработать с foreach, но меня js заставляет использовать async в стрелочной функции из-за чего подгрузка информации о пользователях не успевает за отображением таблицы. Если несложно подскажите возможные пути оптимизации того, что я натворил.

    Код:
    
            const items await Context.fields.razdely.fetchAll();
            
    let xnumber Context.data.razdely!.length;

            for (var 
    0xi++)
            {
                
    user_created.push((await items[i].data.__createdBy.fetch()).data.__name)
                
    user_updated.push((await items[i].data.__updatedBy.fetch()).data.__name)
            }

            
    ViewContext.data.mainInfo items;
            
    ViewContext.data.polzovatelCreator user_created
            ViewContext
    .data.polzovatelEditor user_updated
    HTML:
    <div class="scroll-table">
        <table>
            <thead>
                <tr>
                    <th width = "4%" class="active">
                        <input type="checkbox" class="select-all checkbox" name="select-all" />
                    </th>
                    <th width = "13%">Раздел</th>
                    <th width = "25%">Описание</th>
                    <th width = "18%">Дата создания</th>
                    <th width = "12%">Создан</th>
                    <th width = "18%">Дата редактирования</th>
                    <th width = "12%">Редактирован</th>
                </tr>
            </thead>
        </table>
        <div class="scroll-table-body" id="mytable">
            <table>
                <tbody>
                    <%
                    var i = 0;
                     for (const item of ViewContext.data.testovaya) { %>
                    <tr>
                        <td width = "4%" class="active">
                            <input type="checkbox" class="select-item checkbox" name="select-item" value=item />
                        </td>
                        <td width = "13%"> <a href='(p:item/ServiceDesk/razdely/<%= item.data.__id %>)'><%= item.data.__name %></a> </td>
                        <td width = "25%"> <%= item.data.opisanie %> </td>
                        <td width = "18%"> <%= item.data.__createdAt.format("hh:mm:ss DD/MM/YYYY") %> </td>
                        <td width = "12%"> <a href='profile/<%= item.data.__createdBy.id %>'> <%= ViewContext.data.eshetest[i] %> </a> </td>
                        <td width = "18%"> <%= item.data.__updatedAt.format("hh:mm:ss DD/MM/YYYY") %> </td>
                        <td width = "12%"> <a href='profile/<%= item.data.__updatedBy.id %>'> <%= ViewContext.data.polzovatelredaktor[i] %> </a> </td>
                    </tr>
                    <% i++; %>
                    <% }
                    %>
                </tbody>
            </table>
        </div>
    </div>
    Последнее редактирование: 27 апр 2022
  7. kurbatov-la

    kurbatov-la Активный участник

    Можно изменить код в сторону использования Promise.all(iterable)

    Тут есть несколько примеров https://community.elma365.com/ru/threads/83/
    https://community.elma365.com/ru/threads/99/
  8. ybgr111

    ybgr111 Участник

    Спасибо, придумал следующее при помощи Promise.all (сегодня не работает вставка в редакторе)

    let createdRequests = items.map(async user => (await user.data.__createdBy.fetch()).data.__name);
    let updatedRequests = items.map(async user => (await user.data.__updatedBy.fetch()).data.__name);

    ViewContext.data.polzovatelCreator = await Promise.all(createdRequests);
    ViewContext.data.polzovatelEditor = await Promise.all(updatedRequests);
  9. kurbatov-la

    kurbatov-la Активный участник

    Изменилась скорость подгрузки элементов?
  10. ybgr111

    ybgr111 Участник

    Да, быстро подгружает