List View

Всем привет!

В прошлой статье мы рассмотрели компонент Query, используемый для написания GraphQL-запросов. И там же описывалось, что сформированный запрос отправляется на API-сервер через компонент Connector, после чего полученный результат выводится на странице через ListView, о котором и пойдет более детальный разговор в этой статье.

На самом деле это тоже очень важный и довольно мощный компонент и использовать его можно не только непосредственно внутри компонента Connector, но и внутри других компонентов для вывода имеющихся в них массивов объектов. Если вы внимательно изучите вот этот пример, то увидите, что компонент ListView используется для вывода комментариев пользователя внутри объекта пользователя.

Давайте внимательней рассмотрим этот пример. В нем выполняется запрос:

query user {
  object: user (
    where: {
      username: "Fi1osof"
    }
  ){
    id
    username
    fullname
    image
    Resources (
      first: 3
      orderBy: createdAt_DESC
      where: {
        type: Comment
      }
    ){
      ...resource
      CommentTarget{
        ...resource
      }
    }
  }
}

fragment resource on Resource{
	id
  name
  content
  uri
}

В нем мы получаем конкретного пользователя по юзернейму. Помимо некоторых полей объекта User мы еще и запрашиваем 3 комментария (подзапрос Resources с типом Comment), а в каждом этом комментарии мы еще и запрашиваем CommentTarget, то есть топик, к которому оставлен комментарий.

В ответ на запрос мы получаем следующие данные с сервера:

{
  "data": {
    "object": {
      "id": "cjoe87z9f001b0d9683ysg0m4",
      "username": "Fi1osof",
      "fullname": "",
      "image": "9da9e7e309fd4e77cf42c02a7a42142e.jpeg",
      "Resources": [
        {
          "id": "cjvs9myrqbx150a8967zkkda4",
          "name": "Дима, в статью дописал ссылку на видео.",
          "uri": "/comments/topics/query.html/dima,-v-statyu-dopisal-ssylku-na-video..html",
          "content": "...",
          "__typename": "Resource",
          "CommentTarget": {
            "id": "cjvs5l3vqbtvo0a895brraes7",
            "name": "Query",
            "uri": "/topics/query.html",
            "content": "...",
            "__typename": "Resource"
          }
        },
        {
          "id": "cjvs8xobxbwn10a89tmi0wxk7",
          "name": "Кстати, на случай, если ты вдруг не понял как реда",
          "uri": "/comments/topics/query.html/kstati,-na-sluchay,-esli-ty-vdrug-ne-ponyal-kak-reda.html",
          "content": "...",
          "__typename": "Resource",
          "CommentTarget": {
            "id": "cjvs5l3vqbtvo0a895brraes7",
            "name": "Query",
            "uri": "/topics/query.html",
            "content": "...",
            "__typename": "Resource"
          }
        },
        {
          "id": "cjvs8t9z8bwin0a89kyf4v6tt",
          "name": "Все, вижу, ты сделал поддомен. Вот на него и надо",
          "uri": "/comments/topics/query.html/vse,-vizhu,-ty-sdelal-poddomen.-vot-na-nego-i-nado.html",
          "content": "...",
          "__typename": "Resource",
          "CommentTarget": {
            "id": "cjvs5l3vqbtvo0a895brraes7",
            "name": "Query",
            "uri": "/topics/query.html",
            "content": "...",
            "__typename": "Resource"
          }
        }
      ],
      "__typename": "User"
    }
  }
}

В шаблоне для вывода объекта пользователя мы используем компонент ObjectView. В нем для вывода комментариев (массива объектов Resources) мы использовали компонент ObjectField, указав ему name=Resources. И вот здесь самое интересное: получив из объекта пользователя массив комментариев Resources, ObjectField, определив, что это массив, передает его в специальный контекст для передачи массива объектов вглубь. Теперь на любом уровне вложенности ниже можно вывести эти объекты в цикле с помощь компонента ListView.

Таким образом ListView можно использовать для вывода в цикле различных Array-свойств объектов. К примеру, посмотрите внимательно еще и вот этот шаблон. В нем я из полученных объектов шаблонов вывожу имена их прямых потомков.

Так же аналогичным способом для вывода вложенных одиночных объектов можно использовать ObjectView.

Второй вариант использования компонента ListView (и он же по сути основной) - это вызов его внутри компонента Connector для вывода полученных данных в цикле. Этот вариант подробно рассматривался в прошлой статье.

Comments

Фактически, это что-то похожее на одноимённый компонент из React Native. То есть, он тоже выполняет ту же функцию вывода массива объектов.

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

Павел, для этого можно тогда просто свой фронт использовать, ведь здесь сервер и фронт живут своей жизнью. Но если хочется именно использовать призму, то вероятно наилучший способ - это использовать @prisma-cms/boilerplate и изменить метод renderWrapper(), прописав свою логику. Так будет и полностью свое оформление, и унаследована основная логика и контексты.

Напомню, что @prisma-cms/boilerplate изначально планировалась как заготовка, используемая для старта проекта и дальнейшего его самостоятельного развития, так что в ней по идее можно делать что хочется.

Но вообще, отказываться от фронт-редактора не стоит. На самом деле ты скорее всего пока не понял его основных фишек (в принципе, я их еще особо не раскрывал). Фронтовый редактор при правильном подходе должен решить ряд очень важных задач и быть в целом полезным. Но я согласен, что в нынешнем виде он не совсем удобен и проще писать свой код привычным способом. Но этот недостаток решается добавлением своих собственных компонентов в него (расширение списка используемых в нем модуле). Я сейчас напишу статейку про это.