ФорумПрограммированиеJavaScriptAngularJS → Ui-Scroll перевод

Ui-Scroll перевод

  • Ivan.

    Сообщения: 494 Репутация: N Группа: Адекваты

    Spritz 24 февраля 2016 г. 3:30

    Перевод angular-ui/ui-scroll [github.com]

    Общий способ представить пользователю список элементов данных неопределенной длины, это начать с отображения небольшой порции верхней части списка. Этого хватит, чтобы заполнить пространство на странице. Дополнительные строки будут добавляться в конец списка, когда пользователь будет крутить его вниз.

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

    Это становится настоящей проблемой, если HTML-код каждого отрендеренного элемента имеет обработчики событий и/или angular-вотчеры. Веб-приложение средней сложности может легко ввести 20 вотчеров на элемент. При этом список из 100 элементов может дать нам в общей сложности 2000 вотчеров и тормоза даже в современных условиях.

    uiScroll directive

    uiScroll решает эту проблему путем динамического удаления/добавления элементов на страницу.

    Описание

    uiScroll подобна ngRepeat. Как и ngRepeat, uiScroll инстанцирует шаблон один раз для каждого элемента из коллекции. Каждый экземпляр шаблона имеет свой SCOPE. Получение элементов списка обеспечивается с источником данных (datasource). Источник данных указывается через scroll_expression. Начиная с V 1.2.0 uiScroll поддерживает анимацию.

    viewport - это элемент, представляющий пространство, в котором рендерятся необходимые элементы из списка. Если viewport не задан при помощи uiScrollViewport директивы (см. ниже), окно браузера будет использоваться в качестве viewport.

    Важно: viewport должен иметь ограниченную высоту (height). Источник данных будет использоваться только тогда, когда элементов внутри viewport недостаточно, чтобы заполнить его по высоте. Если высота области просмотра не ограничивается (style="height: auto") viewport будет тянуть все содержимое datasource и может выдавать сообщение об ошибке, в зависимости от количества элементов в источнике данных. Даже если это не так, используя директиву этот способ не дает никаких преимуществ по сравнению с использованием ng-repeat, потому что шаблон элемента всегда будет инстанцирован для каждого элемента в источнике данных.

    Зависимости

    При использовании убедитесь, что ui-scroll.js (как transpiled из ui-scroll.coffee) подключен.
    Вы также должны включить модуль 'ui.scroll' в список зависимостей главного модуля вашего приложения.

    Код uiScroll базируется на некоторых функциях jQuery, которые в настоящее время не реализован в jQlite, а именно:
    - before(elem)
    - height() и height(value)
    - outerHeight() и outerHeight(true)
    - scrollTop() и scrollTop(value)
    - offset()

    Файл ui-scroll-jqlite.coffee содержит вышеуказанные функции, и также должен быть подключен на вашей странице. Обратите внимание, что методы реализуются в отдельном модуле 'ui.scroll.jqlite' и эта строчка должна также быть включена в список зависимостей вашего главного модуля. Протестировано на IE8 и выше, а также на Chrome 28 и Firefox 20.

    Этот модуль необходим, если вы планируете использовать ui-scroll без библиотеки jQuery. Если jQuery присутствует, uiScroll будет использовать jQuery.

    Использование

    <ANY ui-scroll="{scroll_expression}" buffer-size="value" padding="value">
          ...
    </ANY>

    ANY на самом деле может быть не совсем любым тегом. Подойдут большинство 'обычных' тегов - DIV, SPAN, A, INPUT и др. Для всех из них viewport должен быть внутри DIV (кроме случая когда используется окно браузера). Некоторые другие теги требуют специального лечения. Если вы используете LI, то лучше всего использовать UL или OL как viewport. Для TR viewport должен быть представлен через TBODY. DL не поддерживается.

    Информация о директиве

    • Эта директива создает новый scope
    • Эта директива использует priority level 1000

    Параметры

    • uiScroll – {scroll_expression} – выражение, показывающее как именно перебирать источник данных. В настоящее время поддерживает только один синтаксис.

      • variable in datasource – где variable это пользовательская переменная элемента цикла и datasource, собственно сам datasource service.

    • buffer-size - value, опционально - количество запрашиваемых элементов из источника данных в одном запросе. По умолчанию равно 10, а минимальное значение 3
    • padding - value, опционально - дополнительная высота добавляемая в viewport для определения того, когда элемент должен быть создан/уничтожен. Определяет чувствительность скроллинга. Значение по умолчанию равно 0.5, а минимальное значение 0.3.
    • adapter - name, опционально - ссылка на объект адаптера для скроллера (позволяет манипулировать элементами списка). Если viewport является окном браузера, adapter будет размещен внутри $rootScope.

    Некоторые свойства, которые имеет адаптер можно также получить непосредственно из директивы, используя соответствующие атрибуты. Так же, как и для адаптера, синтаксис для таких атрибутов позволяет создать переменную, которая будет использоваться для доступа к соответствующему значению. Если viewport является окном браузера, значение будет находиться внутри $rootScope. Ниже приведен список таких атрибутов:

    • is-loading - name, опционально - boolean значение, сигнализирующее о загрузке данных из datasource. Смотрите также isLoading adapter property.
    • top-visible - name, опционально - ссылка на переменную, содержащую в себе полностью видимый элемент списка, который находится в самом верху видимой области. Смотрите также topVisible adapter property.
    • top-visible-element - name, опционально - ссылка на DOM element находящийся в видимой области в самом верху и полностью отображаемый. Смотрите также topVisibleElement adapter property.
    • top-visible-scope - name, опционально - ссылка на scope, созданный для элемента, находящегося в видимой области в самом верху и полностью отображаемый. Смотрите также topVisibleScope adapter property.

    Источник данных

    Источник данных это объект, используемый uiScroll для доступа к данным.
    uiScroll будет находить элементы используя имя datasource. Cперва uiScroll будет искать свойство с заданным именем внутри $scope. При отсутствии, будет использоваться get на angular service с указанным именем.
    Datasource объект реализует методы и свойства, которые будут использоваться директивы для доступа к данным:

    Метод get

    get(descriptor, success)

    или

    get(index, count, success)

    Описание метода

    Это обязательный метод, который используется в директиве для извлечения данных.

    Параметры

    • descriptor это объект, определяющий часть запрошенных данных. Объект имеет 3 свойства. Два из них с именем index и count. Они имеют такое же значение, как и в альтернативе, когда параметры, передаются явно (см. ниже). Третий будет называться либо append, если элементы будут добавлены в конец буфера, или prepend, если они будут добавлены в начало. Значение property может быть элементом, а новые элементы будут добавлены через append/prepend. Это полезно, если легче определить элементы, которые будут добавлены с учетом ранее запрошенных элементов, а не по индексу. Имейте в виду, что в определенных случаях (т.е. по первоначальной загрузке) значение append/prepend property может быть не задано.
    • index указывает на первый элемент запрошенных данных
    • count указывает на количество запрошенных данных
    • success функция, которая вызывается при завершении загрузки данных. Реализация источника данных (datasource) должна вызывать эту функцию, когда данные загружены и передать в него массив загруженных элементов. Если элементы не загружены - необходимо передать функции пустой массив.

    Важно: используйте параметры index и count. Массив, переданный методу success, должен содержать точно count элементов за исключением eof/bof (запрашивается больше данных чем имеется)

    Адаптер

    Адаптер - это внутренний объект, который создается для каждого экземпляра скроллера. Свойства и методы адаптера могут использоваться для управления и анализа текущего состояния скроллера.

    Адаптер содержит в себе следующие параметры:

    • isLoading - boolean значение, сигнализирующее о загрузке данных из datasource.
    • topVisible - ссылка на переменную, содержащую в себе полностью видимый элемент списка, который находится в самом верху видимой области.
    • topVisibleElement - ссылка на DOM element находящийся в видимой области в самом верху и полностью отображаемый.
    • topVisibleScope -ссылка на scope, созданный для элемента, находящегося в видимой области в самом верху и полностью отображаемый.

    Адаптер содержит в себе следующие методы:

    Метод reload

    reload()

    or

    reload(startIndex)

    Описание метода

    Вызов этого метода повторно инициализирует и загружает содержимое скроллера. startIndex это целое число, указывающее, с какого элемента списка будет инициализирован процесс загрузки. Вызов reload() эквивалентен вызову reload(1).

    Важно: startIndex должен быть в пределах границ базового набора данных. Скроллер будет запрашивать две партии отдельных элементов, начиная с индекса startindex и еще одна, предшествующая первой (начиная со startIndex минус bufferSize). Если оба запросы возвращаются пустыми, скроллер будет думать что набор данных пустой и не будет делать никаких дополнительных запросов.

    Метод applyUpdates

    applyUpdates(index, newItems)

    Описание метода

    Заменяет элемент в буфере по данному индексу index новыми элементами newItems.

    Параметры

    index ссылается на индекс элемента в наборе данных (не в буфере). Если элемент с заданным индексом в настоящее время не находится в буфере - обновления не будут применены. $index property элемента $scope может быть использовано для доступа к индексу для данного элемента.
    newItems это массив элементов для замены указанного элемента. Если массив пустой ([]) элемент будет удален, в противном случае заменен новыми элементами. Если newItem массив содержит старый элемент, старый элемент останется на прежнем месте.

    applyUpdates(updater)

    Описание метода

    Обновляет контент скроллера при помощи функции updater

    Параметры

    updater это функция, которая будет применена к каждому элементу внутри буфера. Функция получит 3 параметра: item, scope, и element. Где item это затронутый элемент, scope это $scope данного элемента, и element это ссылка на html элемент. Возвращаемое значение функции должен быть массив элементов. Точно также как и newItem параметр (см. выше), если массив пустой ([]), элемент будет удален, в противном случае заменен новыми элементами из массива. Если возвращаемое значение не массив, элемент останется не затронутым, кроме каких-либо манипуляций, проделанных внутри функции updater.

    Метод append

    append(newItems)

    Описание метода

    Добавляет новые элементы после последнего элемента в буфере.

    Параметры

    newItems содержит массив элементов, которые будут добавлены.

    Метод prepend

    prepend(newItems)

    Описание метода

    Добавляет новые элементов до первого элемента в буфере.

    Параметры

    newItems содержит массив элементов, которые будут добавлены.

    Манипулирование scroller content при помощи методов адаптера

    Методы адаптера applyUpdates, append и prepend предоставляют способ обновить скроллер-контент без полной перезагрузки содержимого из источника данных. Обновления выполняются путем изменения элементов внутреннего буфера скроллера после того, как они загружаются из источника данных. Элементы в буфере могут быть удалены или заменены.

    Важно: обновление datasource должно совпадать со scroller buffer content: имейте в виду, что внесенные изменения с помощью адаптера применяются только к содержимому буфера и вы можете потерять изменения при скроллинге. Это ваша ответственность, ведь когда скроллер прокручивается обратно и измененный элемент запрашивается из источника данных снова - возвращаемый источником данных элемент будет отражать обновленное состояние. Другими словами, вы должны убедиться, что кроме манипулирования скроллер-контента вы также изменяете набор данных базового источника данных.

    Анимации

    Как и в ngRepeat поддерживаются анимации:

    • .enter - когда элемент добавляется в список
    • .leave - когда элемент удаляется из списка
      Анимации поддерживаются только когда используется applyUpdates метод. Обновления по причине скроллинга не подвержены анимации. Обычные правила работают с Angular-анимацией. Смотрите тут для примера анимации списка.

    uiScrollViewport директива

    Описание директивы

    uiScrollViewport представляет собой определенный элемент viewport для uiScroll.

    Использование

    <ANY ui-scroll-viewport>
          ...
    </ANY>

    Примеры

    Примеры (смотрите тут) содержат несколько страниц (.html файлы) демонстрирующие различные пути использования ui-scroll. Каждая страница относится к её собственному datasource service (назваемый datasource) указанному внутри coffescript file с таким же именем и .coffee расширением.

    Я намеренно нарушаю правила правильной html/css структуры (т.е. встроенные стили). Это делается, чтобы сохранить HTML как есть, как это возможно, и оставить его вам, чтобы вы делали с ним всё что хотите.

    Смотрите index.html

  • phpdude

    Сообщения: 26624 Репутация: N Группа: в ухо

    Spritz 24 февраля 2016 г. 4:00, спустя 29 минут 50 секунд

    Не читал но начало многообещающее. Профиль решил сменить?) Из девов в переводчики?

    Сапожник без сапог
  • Ivan.

    Сообщения: 494 Репутация: N Группа: Адекваты

    Spritz 24 февраля 2016 г. 4:36, спустя 35 минут 42 секунды

    Не читал но начало многообещающее. Профиль решил сменить?) Из девов в переводчики?

    @phpdude, я это для самого себя перевел. Решил что так лучше смогу разобраться что к чему. Не очень интуитивно понятная либа, но альтернатив пока не нашел адекватных.

  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 24 февраля 2016 г. 4:57, спустя 21 минуту 35 секунд

    @Ivan., спасибо, полезное дело. Почитаю вечерком +1

    adw/0
  • technobulka

    Сообщения: 4540 Репутация: N Группа: Джедаи

    Spritz 24 февраля 2016 г. 21:46, спустя 16 часов 48 минут 53 секунды

    Что-то вот тут лагает при прокрутке вверх.

    Высокоуровневое абстрактное говно
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 25 февраля 2016 г. 0:48, спустя 3 часа 2 минуты

    @technobulka, адски причем

    adw/0
  • Sinkler

    Сообщения: 8083 Репутация: N Группа: в ухо

    Spritz 25 февраля 2016 г. 1:02, спустя 13 минут 13 секунд

    в фф ещё и если после этого покрутить вниз вообще непонятно что происходит

  • Ivan.

    Сообщения: 494 Репутация: N Группа: Адекваты

    Spritz 25 февраля 2016 г. 2:50, спустя 1 час 48 минут 42 секунды

    для чата самое то, есть что предложить лучше?

  • artoodetoo

    Сообщения: 5139 Репутация: N Группа: в ухо

    Spritz 25 февраля 2016 г. 5:33, спустя 2 часа 43 минуты 10 секунд

    Не ангуляр можно предложить.

    ιιlllιlllι унц-унц
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 25 февраля 2016 г. 6:07, спустя 33 минуты 56 секунд

    @artoodetoo, а что конкретно?

    adw/0
  • Ivan.

    Сообщения: 494 Репутация: N Группа: Адекваты

    Spritz 25 февраля 2016 г. 8:16, спустя 2 часа 8 минут 10 секунд

    Или не на ангуляре даже? Не могу найти вообще ничего подобного

  • phpdude

    Сообщения: 26624 Репутация: N Группа: в ухо

    Spritz 25 февраля 2016 г. 8:20, спустя 4 минуты 37 секунд

    react? :)

    Спустя 70 сек.

    сразу скажу - я топик не читал

    Сапожник без сапог
  • Ivan.

    Сообщения: 494 Репутация: N Группа: Адекваты

    Spritz 25 февраля 2016 г. 9:56, спустя 1 час 36 минут 2 секунды

    че реакт? а че не питон?)

  • Ivan.

    Сообщения: 494 Репутация: N Группа: Адекваты

    Spritz 25 февраля 2016 г. 10:03, спустя 6 минут 49 секунд

    магическая формула для datasource.get для чата с использованием UI-SCROLL и сообщениями в подобном порядке [0,1,2,3,4,5,6,7,8,9,10...]:
    U = множество сообщений
    index = посылаемый индекс
    count = посылаемый count
    n = |U| (кол-во сообщений)
    a = n + index
    b = a + count - 1
    нужные сообщения чата будут находиться с a по b

  • artoodetoo

    Сообщения: 5139 Репутация: N Группа: в ухо

    Spritz 25 февраля 2016 г. 11:26, спустя 1 час 23 минуты 1 секунду

    @artoodetoo, а что конкретно?

    @adw0rd, смотря какуб цель ставить. Я просто дам ссылку на
    хрень в действии, ок? Word association game - Flarum Community [discuss.flarum.org]
    Реально я не считаю, что надо из-за одного элемента менять ориентацию.

    ιιlllιlllι унц-унц

Пожалуйста, авторизуйтесь, чтобы написать комментарий!